OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / final.c
index 86b0b2f..bf5771a 100644 (file)
@@ -1,6 +1,6 @@
 /* Convert RTL to assembler code and output it, for GNU compiler.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
 /* Convert RTL to assembler code and output it, for GNU compiler.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 
 This file is part of GCC.
 
@@ -81,6 +81,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "dwarf2out.h"
 #endif
 
 #include "dwarf2out.h"
 #endif
 
+#ifdef DBX_DEBUGGING_INFO
+#include "dbxout.h"
+#endif
+
 /* If we aren't using cc0, CC_STATUS_INIT shouldn't exist.  So define a
    null default for it to save conditionalization later.  */
 #ifndef CC_STATUS_INIT
 /* If we aren't using cc0, CC_STATUS_INIT shouldn't exist.  So define a
    null default for it to save conditionalization later.  */
 #ifndef CC_STATUS_INIT
@@ -107,6 +111,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #define HAVE_READONLY_DATA_SECTION 0
 #endif
 
 #define HAVE_READONLY_DATA_SECTION 0
 #endif
 
+/* Bitflags used by final_scan_insn.  */
+#define SEEN_BB                1
+#define SEEN_NOTE      2
+#define SEEN_EMITTED   4
+
 /* Last insn processed by final_scan_insn.  */
 static rtx debug_insn;
 rtx current_output_insn;
 /* Last insn processed by final_scan_insn.  */
 static rtx debug_insn;
 rtx current_output_insn;
@@ -166,9 +175,15 @@ CC_STATUS cc_prev_status;
 
 char regs_ever_live[FIRST_PSEUDO_REGISTER];
 
 
 char regs_ever_live[FIRST_PSEUDO_REGISTER];
 
+/* Like regs_ever_live, but 1 if a reg is set or clobbered from an asm.
+   Unlike regs_ever_live, elements of this array corresponding to
+   eliminable regs like the frame pointer are set if an asm sets them.  */
+
+char regs_asm_clobbered[FIRST_PSEUDO_REGISTER];
+
 /* Nonzero means current function must be given a frame pointer.
 /* Nonzero means current function must be given a frame pointer.
-   Set in stmt.c if anything is allocated on the stack there.
-   Set in reload1.c if anything is allocated on the stack there.  */
+   Initialized in function.c to 0.  Set only in reload1.c as per
+   the needs of the function.  */
 
 int frame_pointer_needed;
 
 
 int frame_pointer_needed;
 
@@ -191,45 +206,40 @@ rtx final_sequence;
 static int dialect_number;
 #endif
 
 static int dialect_number;
 #endif
 
-/* Indexed by line number, nonzero if there is a note for that line.  */
-
-static char *line_note_exists;
-
 #ifdef HAVE_conditional_execution
 /* Nonnull if the insn currently being emitted was a COND_EXEC pattern.  */
 rtx current_insn_predicate;
 #endif
 
 #ifdef HAVE_ATTR_length
 #ifdef HAVE_conditional_execution
 /* Nonnull if the insn currently being emitted was a COND_EXEC pattern.  */
 rtx current_insn_predicate;
 #endif
 
 #ifdef HAVE_ATTR_length
-static int asm_insn_count      PARAMS ((rtx));
-#endif
-static void profile_function   PARAMS ((FILE *));
-static void profile_after_prologue PARAMS ((FILE *));
-static void notice_source_line PARAMS ((rtx));
-static rtx walk_alter_subreg   PARAMS ((rtx *));
-static void output_asm_name    PARAMS ((void));
-static void output_alternate_entry_point PARAMS ((FILE *, rtx));
-static tree get_mem_expr_from_op       PARAMS ((rtx, int *));
-static void output_asm_operand_names PARAMS ((rtx *, int *, int));
-static void output_operand     PARAMS ((rtx, int));
+static int asm_insn_count (rtx);
+#endif
+static void profile_function (FILE *);
+static void profile_after_prologue (FILE *);
+static bool notice_source_line (rtx);
+static rtx walk_alter_subreg (rtx *);
+static void output_asm_name (void);
+static void output_alternate_entry_point (FILE *, rtx);
+static tree get_mem_expr_from_op (rtx, int *);
+static void output_asm_operand_names (rtx *, int *, int);
+static void output_operand (rtx, int);
 #ifdef LEAF_REGISTERS
 #ifdef LEAF_REGISTERS
-static void leaf_renumber_regs PARAMS ((rtx));
+static void leaf_renumber_regs (rtx);
 #endif
 #ifdef HAVE_cc0
 #endif
 #ifdef HAVE_cc0
-static int alter_cond          PARAMS ((rtx));
+static int alter_cond (rtx);
 #endif
 #ifndef ADDR_VEC_ALIGN
 #endif
 #ifndef ADDR_VEC_ALIGN
-static int final_addr_vec_align PARAMS ((rtx));
+static int final_addr_vec_align (rtx);
 #endif
 #ifdef HAVE_ATTR_length
 #endif
 #ifdef HAVE_ATTR_length
-static int align_fuzz          PARAMS ((rtx, rtx, int, unsigned));
+static int align_fuzz (rtx, rtx, int, unsigned);
 #endif
 \f
 /* Initialize data in final at the beginning of a compilation.  */
 
 void
 #endif
 \f
 /* Initialize data in final at the beginning of a compilation.  */
 
 void
-init_final (filename)
-     const char *filename ATTRIBUTE_UNUSED;
+init_final (const char *filename ATTRIBUTE_UNUSED)
 {
   app_on = 0;
   final_sequence = 0;
 {
   app_on = 0;
   final_sequence = 0;
@@ -244,16 +254,14 @@ init_final (filename)
    If not overridden for epilogue code, then the function body itself
    contains return instructions wherever needed.  */
 void
    If not overridden for epilogue code, then the function body itself
    contains return instructions wherever needed.  */
 void
-default_function_pro_epilogue (file, size)
-     FILE *file ATTRIBUTE_UNUSED;
-     HOST_WIDE_INT size ATTRIBUTE_UNUSED;
+default_function_pro_epilogue (FILE *file ATTRIBUTE_UNUSED,
+                              HOST_WIDE_INT size ATTRIBUTE_UNUSED)
 {
 }
 
 /* Default target hook that outputs nothing to a stream.  */
 void
 {
 }
 
 /* Default target hook that outputs nothing to a stream.  */
 void
-no_asm_to_stream (file)
-     FILE *file ATTRIBUTE_UNUSED;
+no_asm_to_stream (FILE *file ATTRIBUTE_UNUSED)
 {
 }
 
 {
 }
 
@@ -261,7 +269,7 @@ no_asm_to_stream (file)
    Used before the output from an `asm' statement.  */
 
 void
    Used before the output from an `asm' statement.  */
 
 void
-app_enable ()
+app_enable (void)
 {
   if (! app_on)
     {
 {
   if (! app_on)
     {
@@ -274,7 +282,7 @@ app_enable ()
    Called from varasm.c before most kinds of output.  */
 
 void
    Called from varasm.c before most kinds of output.  */
 
 void
-app_disable ()
+app_disable (void)
 {
   if (app_on)
     {
 {
   if (app_on)
     {
@@ -289,7 +297,7 @@ app_disable ()
 
 #ifdef DELAY_SLOTS
 int
 
 #ifdef DELAY_SLOTS
 int
-dbr_sequence_length ()
+dbr_sequence_length (void)
 {
   if (final_sequence != 0)
     return XVECLEN (final_sequence, 0) - 1;
 {
   if (final_sequence != 0)
     return XVECLEN (final_sequence, 0) - 1;
@@ -342,7 +350,7 @@ static struct label_alignment *label_align;
 /* Indicate that branch shortening hasn't yet been done.  */
 
 void
 /* Indicate that branch shortening hasn't yet been done.  */
 
 void
-init_insn_lengths ()
+init_insn_lengths (void)
 {
   if (uid_shuid)
     {
 {
   if (uid_shuid)
     {
@@ -369,8 +377,7 @@ init_insn_lengths ()
    get its actual length.  Otherwise, get its maximum length.  */
 
 int
    get its actual length.  Otherwise, get its maximum length.  */
 
 int
-get_attr_length (insn)
-     rtx insn ATTRIBUTE_UNUSED;
+get_attr_length (rtx insn ATTRIBUTE_UNUSED)
 {
 #ifdef HAVE_ATTR_length
   rtx body;
 {
 #ifdef HAVE_ATTR_length
   rtx body;
@@ -504,8 +511,7 @@ get_attr_length (insn)
 
 #ifndef ADDR_VEC_ALIGN
 static int
 
 #ifndef ADDR_VEC_ALIGN
 static int
-final_addr_vec_align (addr_vec)
-     rtx addr_vec;
+final_addr_vec_align (rtx addr_vec)
 {
   int align = GET_MODE_SIZE (GET_MODE (PATTERN (addr_vec)));
 
 {
   int align = GET_MODE_SIZE (GET_MODE (PATTERN (addr_vec)));
 
@@ -535,8 +541,7 @@ static int min_labelno, max_labelno;
 /* For the benefit of port specific code do this also as a function.  */
 
 int
 /* For the benefit of port specific code do this also as a function.  */
 
 int
-label_to_alignment (label)
-     rtx label;
+label_to_alignment (rtx label)
 {
   return LABEL_TO_ALIGNMENT (label);
 }
 {
   return LABEL_TO_ALIGNMENT (label);
 }
@@ -571,10 +576,7 @@ label_to_alignment (label)
    The return value is undefined for any other value of GROWTH.  */
 
 static int
    The return value is undefined for any other value of GROWTH.  */
 
 static int
-align_fuzz (start, end, known_align_log, growth)
-     rtx start, end;
-     int known_align_log;
-     unsigned growth;
+align_fuzz (rtx start, rtx end, int known_align_log, unsigned int growth)
 {
   int uid = INSN_UID (start);
   rtx align_label;
 {
   int uid = INSN_UID (start);
   rtx align_label;
@@ -613,8 +615,7 @@ align_fuzz (start, end, known_align_log, growth)
    to exclude the branch size.  */
 
 int
    to exclude the branch size.  */
 
 int
-insn_current_reference_address (branch)
-     rtx branch;
+insn_current_reference_address (rtx branch)
 {
   rtx dest, seq;
   int seq_uid;
 {
   rtx dest, seq;
   int seq_uid;
@@ -624,7 +625,7 @@ insn_current_reference_address (branch)
 
   seq = NEXT_INSN (PREV_INSN (branch));
   seq_uid = INSN_UID (seq);
 
   seq = NEXT_INSN (PREV_INSN (branch));
   seq_uid = INSN_UID (seq);
-  if (GET_CODE (branch) != JUMP_INSN)
+  if (!JUMP_P (branch))
     /* This can happen for example on the PA; the objective is to know the
        offset to address something in front of the start of the function.
        Thus, we can treat it like a backward branch.
     /* This can happen for example on the PA; the objective is to know the
        offset to address something in front of the start of the function.
        Thus, we can treat it like a backward branch.
@@ -651,7 +652,7 @@ insn_current_reference_address (branch)
 #endif /* HAVE_ATTR_length */
 \f
 void
 #endif /* HAVE_ATTR_length */
 \f
 void
-compute_alignments ()
+compute_alignments (void)
 {
   int log, max_skip, max_log;
   basic_block bb;
 {
   int log, max_skip, max_log;
   basic_block bb;
@@ -664,8 +665,8 @@ compute_alignments ()
 
   max_labelno = max_label_num ();
   min_labelno = get_first_label_num ();
 
   max_labelno = max_label_num ();
   min_labelno = get_first_label_num ();
-  label_align = (struct label_alignment *)
-    xcalloc (max_labelno - min_labelno + 1, sizeof (struct label_alignment));
+  label_align = xcalloc (max_labelno - min_labelno + 1,
+                        sizeof (struct label_alignment));
 
   /* If not optimizing or optimizing for size, don't assign any alignments.  */
   if (! optimize || optimize_size)
 
   /* If not optimizing or optimizing for size, don't assign any alignments.  */
   if (! optimize || optimize_size)
@@ -673,17 +674,18 @@ compute_alignments ()
 
   FOR_EACH_BB (bb)
     {
 
   FOR_EACH_BB (bb)
     {
-      rtx label = bb->head;
+      rtx label = BB_HEAD (bb);
       int fallthru_frequency = 0, branch_frequency = 0, has_fallthru = 0;
       edge e;
       int fallthru_frequency = 0, branch_frequency = 0, has_fallthru = 0;
       edge e;
+      edge_iterator ei;
 
 
-      if (GET_CODE (label) != CODE_LABEL
+      if (!LABEL_P (label)
          || probably_never_executed_bb_p (bb))
        continue;
       max_log = LABEL_ALIGN (label);
       max_skip = LABEL_ALIGN_MAX_SKIP;
 
          || probably_never_executed_bb_p (bb))
        continue;
       max_log = LABEL_ALIGN (label);
       max_skip = LABEL_ALIGN_MAX_SKIP;
 
-      for (e = bb->pred; e; e = e->pred_next)
+      FOR_EACH_EDGE (e, ei, bb->preds)
        {
          if (e->flags & EDGE_FALLTHRU)
            has_fallthru = 1, fallthru_frequency += EDGE_FREQUENCY (e);
        {
          if (e->flags & EDGE_FALLTHRU)
            has_fallthru = 1, fallthru_frequency += EDGE_FREQUENCY (e);
@@ -736,12 +738,6 @@ compute_alignments ()
 /* Make a pass over all insns and compute their actual lengths by shortening
    any branches of variable length if possible.  */
 
 /* Make a pass over all insns and compute their actual lengths by shortening
    any branches of variable length if possible.  */
 
-/* Give a default value for the lowest address in a function.  */
-
-#ifndef FIRST_INSN_ADDRESS
-#define FIRST_INSN_ADDRESS 0
-#endif
-
 /* shorten_branches might be called multiple times:  for example, the SH
    port splits out-of-range conditional branches in MACHINE_DEPENDENT_REORG.
    In order to do this, it needs proper length information, which it obtains
 /* shorten_branches might be called multiple times:  for example, the SH
    port splits out-of-range conditional branches in MACHINE_DEPENDENT_REORG.
    In order to do this, it needs proper length information, which it obtains
@@ -751,8 +747,7 @@ compute_alignments ()
    slots.  */
 
 void
    slots.  */
 
 void
-shorten_branches (first)
-     rtx first ATTRIBUTE_UNUSED;
+shorten_branches (rtx first ATTRIBUTE_UNUSED)
 {
   rtx insn;
   int max_uid;
 {
   rtx insn;
   int max_uid;
@@ -773,7 +768,10 @@ shorten_branches (first)
   /* Compute maximum UID and allocate label_align / uid_shuid.  */
   max_uid = get_max_uid ();
 
   /* Compute maximum UID and allocate label_align / uid_shuid.  */
   max_uid = get_max_uid ();
 
-  uid_shuid = (int *) xmalloc (max_uid * sizeof *uid_shuid);
+  /* Free uid_shuid before reallocating it.  */
+  free (uid_shuid);
+  
+  uid_shuid = xmalloc (max_uid * sizeof *uid_shuid);
 
   if (max_labelno != max_label_num ())
     {
 
   if (max_labelno != max_label_num ())
     {
@@ -786,13 +784,12 @@ shorten_branches (first)
       n_labels = max_labelno - min_labelno + 1;
       n_old_labels = old - min_labelno + 1;
 
       n_labels = max_labelno - min_labelno + 1;
       n_old_labels = old - min_labelno + 1;
 
-      label_align = (struct label_alignment *) xrealloc
-       (label_align, n_labels * sizeof (struct label_alignment));
+      label_align = xrealloc (label_align,
+                             n_labels * sizeof (struct label_alignment));
 
       /* Range of labels grows monotonically in the function.  Abort here
          means that the initialization of array got lost.  */
 
       /* Range of labels grows monotonically in the function.  Abort here
          means that the initialization of array got lost.  */
-      if (n_old_labels > n_labels)
-       abort ();
+      gcc_assert (n_old_labels <= n_labels);
 
       memset (label_align + n_old_labels, 0,
              (n_labels - n_old_labels) * sizeof (struct label_alignment));
 
       memset (label_align + n_old_labels, 0,
              (n_labels - n_old_labels) * sizeof (struct label_alignment));
@@ -820,7 +817,7 @@ shorten_branches (first)
              is separated by the former loop start insn from the
             NOTE_INSN_LOOP_BEG.  */
        }
              is separated by the former loop start insn from the
             NOTE_INSN_LOOP_BEG.  */
        }
-      else if (GET_CODE (insn) == CODE_LABEL)
+      else if (LABEL_P (insn))
        {
          rtx next;
 
        {
          rtx next;
 
@@ -842,7 +839,7 @@ shorten_branches (first)
          /* ADDR_VECs only take room if read-only data goes into the text
             section.  */
          if (JUMP_TABLES_IN_TEXT_SECTION || !HAVE_READONLY_DATA_SECTION)
          /* ADDR_VECs only take room if read-only data goes into the text
             section.  */
          if (JUMP_TABLES_IN_TEXT_SECTION || !HAVE_READONLY_DATA_SECTION)
-           if (next && GET_CODE (next) == JUMP_INSN)
+           if (next && JUMP_P (next))
              {
                rtx nextbody = PATTERN (next);
                if (GET_CODE (nextbody) == ADDR_VEC
              {
                rtx nextbody = PATTERN (next);
                if (GET_CODE (nextbody) == ADDR_VEC
@@ -861,13 +858,13 @@ shorten_branches (first)
          max_log = 0;
          max_skip = 0;
        }
          max_log = 0;
          max_skip = 0;
        }
-      else if (GET_CODE (insn) == BARRIER)
+      else if (BARRIER_P (insn))
        {
          rtx label;
 
          for (label = insn; label && ! INSN_P (label);
               label = NEXT_INSN (label))
        {
          rtx label;
 
          for (label = insn; label && ! INSN_P (label);
               label = NEXT_INSN (label))
-           if (GET_CODE (label) == CODE_LABEL)
+           if (LABEL_P (label))
              {
                log = LABEL_ALIGN_AFTER_BARRIER (insn);
                if (max_log < log)
              {
                log = LABEL_ALIGN_AFTER_BARRIER (insn);
                if (max_log < log)
@@ -882,20 +879,20 @@ shorten_branches (first)
 #ifdef HAVE_ATTR_length
 
   /* Allocate the rest of the arrays.  */
 #ifdef HAVE_ATTR_length
 
   /* Allocate the rest of the arrays.  */
-  insn_lengths = (int *) xmalloc (max_uid * sizeof (*insn_lengths));
+  insn_lengths = xmalloc (max_uid * sizeof (*insn_lengths));
   insn_lengths_max_uid = max_uid;
   /* Syntax errors can lead to labels being outside of the main insn stream.
      Initialize insn_addresses, so that we get reproducible results.  */
   INSN_ADDRESSES_ALLOC (max_uid);
 
   insn_lengths_max_uid = max_uid;
   /* Syntax errors can lead to labels being outside of the main insn stream.
      Initialize insn_addresses, so that we get reproducible results.  */
   INSN_ADDRESSES_ALLOC (max_uid);
 
-  varying_length = (char *) xcalloc (max_uid, sizeof (char));
+  varying_length = xcalloc (max_uid, sizeof (char));
 
   /* Initialize uid_align.  We scan instructions
      from end to start, and keep in align_tab[n] the last seen insn
      that does an alignment of at least n+1, i.e. the successor
      in the alignment chain for an insn that does / has a known
      alignment of n.  */
 
   /* Initialize uid_align.  We scan instructions
      from end to start, and keep in align_tab[n] the last seen insn
      that does an alignment of at least n+1, i.e. the successor
      in the alignment chain for an insn that does / has a known
      alignment of n.  */
-  uid_align = (rtx *) xcalloc (max_uid, sizeof *uid_align);
+  uid_align = xcalloc (max_uid, sizeof *uid_align);
 
   for (i = MAX_CODE_ALIGN; --i >= 0;)
     align_tab[i] = NULL_RTX;
 
   for (i = MAX_CODE_ALIGN; --i >= 0;)
     align_tab[i] = NULL_RTX;
@@ -904,7 +901,7 @@ shorten_branches (first)
     {
       int uid = INSN_UID (seq);
       int log;
     {
       int uid = INSN_UID (seq);
       int log;
-      log = (GET_CODE (seq) == CODE_LABEL ? LABEL_TO_ALIGNMENT (seq) : 0);
+      log = (LABEL_P (seq) ? LABEL_TO_ALIGNMENT (seq) : 0);
       uid_align[uid] = align_tab[0];
       if (log)
        {
       uid_align[uid] = align_tab[0];
       if (log)
        {
@@ -931,13 +928,12 @@ shorten_branches (first)
          int min_align;
          addr_diff_vec_flags flags;
 
          int min_align;
          addr_diff_vec_flags flags;
 
-         if (GET_CODE (insn) != JUMP_INSN
+         if (!JUMP_P (insn)
              || GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC)
            continue;
          pat = PATTERN (insn);
          len = XVECLEN (pat, 1);
              || GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC)
            continue;
          pat = PATTERN (insn);
          len = XVECLEN (pat, 1);
-         if (len <= 0)
-           abort ();
+         gcc_assert (len > 0);
          min_align = MAX_CODE_ALIGN;
          for (min = max_shuid, max = min_shuid, i = len - 1; i >= 0; i--)
            {
          min_align = MAX_CODE_ALIGN;
          for (min = max_shuid, max = min_shuid, i = len - 1; i >= 0; i--)
            {
@@ -960,6 +956,7 @@ shorten_branches (first)
          XEXP (pat, 3) = gen_rtx_LABEL_REF (VOIDmode, max_lab);
          insn_shuid = INSN_SHUID (insn);
          rel = INSN_SHUID (XEXP (XEXP (pat, 0), 0));
          XEXP (pat, 3) = gen_rtx_LABEL_REF (VOIDmode, max_lab);
          insn_shuid = INSN_SHUID (insn);
          rel = INSN_SHUID (XEXP (XEXP (pat, 0), 0));
+         memset (&flags, 0, sizeof (flags));
          flags.min_align = min_align;
          flags.base_after_vec = rel > insn_shuid;
          flags.min_after_vec  = min > insn_shuid;
          flags.min_align = min_align;
          flags.base_after_vec = rel > insn_shuid;
          flags.min_after_vec  = min > insn_shuid;
@@ -972,7 +969,7 @@ shorten_branches (first)
 #endif /* CASE_VECTOR_SHORTEN_MODE */
 
   /* Compute initial lengths, addresses, and varying flags for each insn.  */
 #endif /* CASE_VECTOR_SHORTEN_MODE */
 
   /* Compute initial lengths, addresses, and varying flags for each insn.  */
-  for (insn_current_address = FIRST_INSN_ADDRESS, insn = first;
+  for (insn_current_address = 0, insn = first;
        insn != 0;
        insn_current_address += insn_lengths[uid], insn = NEXT_INSN (insn))
     {
        insn != 0;
        insn_current_address += insn_lengths[uid], insn = NEXT_INSN (insn))
     {
@@ -980,7 +977,7 @@ shorten_branches (first)
 
       insn_lengths[uid] = 0;
 
 
       insn_lengths[uid] = 0;
 
-      if (GET_CODE (insn) == CODE_LABEL)
+      if (LABEL_P (insn))
        {
          int log = LABEL_TO_ALIGNMENT (insn);
          if (log)
        {
          int log = LABEL_TO_ALIGNMENT (insn);
          if (log)
@@ -993,8 +990,8 @@ shorten_branches (first)
 
       INSN_ADDRESSES (uid) = insn_current_address + insn_lengths[uid];
 
 
       INSN_ADDRESSES (uid) = insn_current_address + insn_lengths[uid];
 
-      if (GET_CODE (insn) == NOTE || GET_CODE (insn) == BARRIER
-         || GET_CODE (insn) == CODE_LABEL)
+      if (NOTE_P (insn) || BARRIER_P (insn)
+         || LABEL_P (insn))
        continue;
       if (INSN_DELETED_P (insn))
        continue;
        continue;
       if (INSN_DELETED_P (insn))
        continue;
@@ -1073,7 +1070,7 @@ shorten_branches (first)
     {
       something_changed = 0;
       insn_current_align = MAX_CODE_ALIGN - 1;
     {
       something_changed = 0;
       insn_current_align = MAX_CODE_ALIGN - 1;
-      for (insn_current_address = FIRST_INSN_ADDRESS, insn = first;
+      for (insn_current_address = 0, insn = first;
           insn != 0;
           insn = NEXT_INSN (insn))
        {
           insn != 0;
           insn = NEXT_INSN (insn))
        {
@@ -1085,7 +1082,7 @@ shorten_branches (first)
 
          uid = INSN_UID (insn);
 
 
          uid = INSN_UID (insn);
 
-         if (GET_CODE (insn) == CODE_LABEL)
+         if (LABEL_P (insn))
            {
              int log = LABEL_TO_ALIGNMENT (insn);
              if (log > insn_current_align)
            {
              int log = LABEL_TO_ALIGNMENT (insn);
              if (log > insn_current_align)
@@ -1110,7 +1107,7 @@ shorten_branches (first)
          INSN_ADDRESSES (uid) = insn_current_address;
 
 #ifdef CASE_VECTOR_SHORTEN_MODE
          INSN_ADDRESSES (uid) = insn_current_address;
 
 #ifdef CASE_VECTOR_SHORTEN_MODE
-         if (optimize && GET_CODE (insn) == JUMP_INSN
+         if (optimize && JUMP_P (insn)
              && GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
            {
              rtx body = PATTERN (insn);
              && GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
            {
              rtx body = PATTERN (insn);
@@ -1220,7 +1217,7 @@ shorten_branches (first)
 
          if (! (varying_length[uid]))
            {
 
          if (! (varying_length[uid]))
            {
-             if (GET_CODE (insn) == INSN
+             if (NONJUMP_INSN_P (insn)
                  && GET_CODE (PATTERN (insn)) == SEQUENCE)
                {
                  int i;
                  && GET_CODE (PATTERN (insn)) == SEQUENCE)
                {
                  int i;
@@ -1242,7 +1239,7 @@ shorten_branches (first)
              continue;
            }
 
              continue;
            }
 
-         if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
+         if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE)
            {
              int i;
 
            {
              int i;
 
@@ -1307,8 +1304,7 @@ shorten_branches (first)
    This is used to compute its length.  */
 
 static int
    This is used to compute its length.  */
 
 static int
-asm_insn_count (body)
-     rtx body;
+asm_insn_count (rtx body)
 {
   const char *template;
   int count = 1;
 {
   const char *template;
   int count = 1;
@@ -1337,35 +1333,21 @@ asm_insn_count (body)
      test and compare insns.  */
 
 void
      test and compare insns.  */
 
 void
-final_start_function (first, file, optimize)
-     rtx first;
-     FILE *file;
-     int optimize ATTRIBUTE_UNUSED;
+final_start_function (rtx first ATTRIBUTE_UNUSED, FILE *file,
+                     int optimize ATTRIBUTE_UNUSED)
 {
   block_depth = 0;
 
   this_is_asm_operands = 0;
 
 {
   block_depth = 0;
 
   this_is_asm_operands = 0;
 
-#ifdef NON_SAVING_SETJMP
-  /* A function that calls setjmp should save and restore all the
-     call-saved registers on a system where longjmp clobbers them.  */
-  if (NON_SAVING_SETJMP && current_function_calls_setjmp)
-    {
-      int i;
+  last_filename = locator_file (prologue_locator);
+  last_linenum = locator_line (prologue_locator);
 
 
-      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-       if (!call_used_regs[i])
-         regs_ever_live[i] = 1;
-    }
-#endif
-
-  if (NOTE_LINE_NUMBER (first) != NOTE_INSN_DELETED)
-    notice_source_line (first);
   high_block_linenum = high_function_linenum = last_linenum;
 
   (*debug_hooks->begin_prologue) (last_linenum, last_filename);
 
   high_block_linenum = high_function_linenum = last_linenum;
 
   (*debug_hooks->begin_prologue) (last_linenum, last_filename);
 
-#if defined (DWARF2_UNWIND_INFO) || defined (IA64_UNWIND_INFO)
+#if defined (DWARF2_UNWIND_INFO) || defined (TARGET_UNWIND_INFO)
   if (write_symbols != DWARF2_DEBUG && write_symbols != VMS_AND_DWARF2_DEBUG)
     dwarf2out_begin_prologue (0, NULL);
 #endif
   if (write_symbols != DWARF2_DEBUG && write_symbols != VMS_AND_DWARF2_DEBUG)
     dwarf2out_begin_prologue (0, NULL);
 #endif
@@ -1384,7 +1366,7 @@ final_start_function (first, file, optimize)
 
 #if defined (DWARF2_UNWIND_INFO) && defined (HAVE_prologue)
   if (dwarf2out_do_frame ())
 
 #if defined (DWARF2_UNWIND_INFO) && defined (HAVE_prologue)
   if (dwarf2out_do_frame ())
-    dwarf2out_frame_debug (NULL_RTX);
+    dwarf2out_frame_debug (NULL_RTX, false);
 #endif
 
   /* If debugging, assign block numbers to all of the blocks in this
 #endif
 
   /* If debugging, assign block numbers to all of the blocks in this
@@ -1392,7 +1374,7 @@ final_start_function (first, file, optimize)
   if (write_symbols)
     {
       remove_unnecessary_notes ();
   if (write_symbols)
     {
       remove_unnecessary_notes ();
-      scope_to_insns_finalize ();
+      reemit_insn_block_notes ();
       number_blocks (current_function_decl);
       /* We never actually put out begin/end notes for the top-level
         block in the function.  But, conceptually, that block is
       number_blocks (current_function_decl);
       /* We never actually put out begin/end notes for the top-level
         block in the function.  But, conceptually, that block is
@@ -1401,7 +1383,7 @@ final_start_function (first, file, optimize)
     }
 
   /* First output the function prologue: code to set up the stack frame.  */
     }
 
   /* First output the function prologue: code to set up the stack frame.  */
-  (*targetm.asm_out.function_prologue) (file, get_frame_size ());
+  targetm.asm_out.function_prologue (file, get_frame_size ());
 
   /* If the machine represents the prologue as RTL, the profiling code must
      be emitted when NOTE_INSN_PROLOGUE_END is scanned.  */
 
   /* If the machine represents the prologue as RTL, the profiling code must
      be emitted when NOTE_INSN_PROLOGUE_END is scanned.  */
@@ -1412,8 +1394,7 @@ final_start_function (first, file, optimize)
 }
 
 static void
 }
 
 static void
-profile_after_prologue (file)
-     FILE *file ATTRIBUTE_UNUSED;
+profile_after_prologue (FILE *file ATTRIBUTE_UNUSED)
 {
 #ifndef PROFILE_BEFORE_PROLOGUE
   if (current_function_profile)
 {
 #ifndef PROFILE_BEFORE_PROLOGUE
   if (current_function_profile)
@@ -1422,40 +1403,33 @@ profile_after_prologue (file)
 }
 
 static void
 }
 
 static void
-profile_function (file)
-     FILE *file ATTRIBUTE_UNUSED;
+profile_function (FILE *file ATTRIBUTE_UNUSED)
 {
 #ifndef NO_PROFILE_COUNTERS
 {
 #ifndef NO_PROFILE_COUNTERS
-  int align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
+# define NO_PROFILE_COUNTERS   0
 #endif
 #if defined(ASM_OUTPUT_REG_PUSH)
 #endif
 #if defined(ASM_OUTPUT_REG_PUSH)
-#if defined(STRUCT_VALUE_INCOMING_REGNUM) || defined(STRUCT_VALUE_REGNUM)
   int sval = current_function_returns_struct;
   int sval = current_function_returns_struct;
-#endif
+  rtx svrtx = targetm.calls.struct_value_rtx (TREE_TYPE (current_function_decl), 1);
 #if defined(STATIC_CHAIN_INCOMING_REGNUM) || defined(STATIC_CHAIN_REGNUM)
 #if defined(STATIC_CHAIN_INCOMING_REGNUM) || defined(STATIC_CHAIN_REGNUM)
-  int cxt = current_function_needs_context;
+  int cxt = cfun->static_chain_decl != NULL;
 #endif
 #endif /* ASM_OUTPUT_REG_PUSH */
 
 #endif
 #endif /* ASM_OUTPUT_REG_PUSH */
 
-#ifndef NO_PROFILE_COUNTERS
-  data_section ();
-  ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
-  (*targetm.asm_out.internal_label) (file, "LP", current_function_funcdef_no);
-  assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1);
-#endif
+  if (! NO_PROFILE_COUNTERS)
+    {
+      int align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
+      data_section ();
+      ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
+      targetm.asm_out.internal_label (file, "LP", current_function_funcdef_no);
+      assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1);
+    }
 
   function_section (current_function_decl);
 
 
   function_section (current_function_decl);
 
-#if defined(STRUCT_VALUE_INCOMING_REGNUM) && defined(ASM_OUTPUT_REG_PUSH)
-  if (sval)
-    ASM_OUTPUT_REG_PUSH (file, STRUCT_VALUE_INCOMING_REGNUM);
-#else
-#if defined(STRUCT_VALUE_REGNUM) && defined(ASM_OUTPUT_REG_PUSH)
-  if (sval)
-    {
-      ASM_OUTPUT_REG_PUSH (file, STRUCT_VALUE_REGNUM);
-    }
-#endif
+#if defined(ASM_OUTPUT_REG_PUSH)
+  if (sval && svrtx != NULL_RTX && REG_P (svrtx))
+    ASM_OUTPUT_REG_PUSH (file, REGNO (svrtx));
 #endif
 
 #if defined(STATIC_CHAIN_INCOMING_REGNUM) && defined(ASM_OUTPUT_REG_PUSH)
 #endif
 
 #if defined(STATIC_CHAIN_INCOMING_REGNUM) && defined(ASM_OUTPUT_REG_PUSH)
@@ -1484,16 +1458,9 @@ profile_function (file)
 #endif
 #endif
 
 #endif
 #endif
 
-#if defined(STRUCT_VALUE_INCOMING_REGNUM) && defined(ASM_OUTPUT_REG_PUSH)
-  if (sval)
-    ASM_OUTPUT_REG_POP (file, STRUCT_VALUE_INCOMING_REGNUM);
-#else
-#if defined(STRUCT_VALUE_REGNUM) && defined(ASM_OUTPUT_REG_PUSH)
-  if (sval)
-    {
-      ASM_OUTPUT_REG_POP (file, STRUCT_VALUE_REGNUM);
-    }
-#endif
+#if defined(ASM_OUTPUT_REG_PUSH)
+  if (sval && svrtx != NULL_RTX && REG_P (svrtx))
+    ASM_OUTPUT_REG_POP (file, REGNO (svrtx));
 #endif
 }
 
 #endif
 }
 
@@ -1502,7 +1469,7 @@ profile_function (file)
    even though not all of them are needed.  */
 
 void
    even though not all of them are needed.  */
 
 void
-final_end_function ()
+final_end_function (void)
 {
   app_disable ();
 
 {
   app_disable ();
 
@@ -1510,7 +1477,7 @@ final_end_function ()
 
   /* Finally, output the function epilogue:
      code to restore the stack frame and return to the caller.  */
 
   /* Finally, output the function epilogue:
      code to restore the stack frame and return to the caller.  */
-  (*targetm.asm_out.function_epilogue) (asm_out_file, get_frame_size ());
+  targetm.asm_out.function_epilogue (asm_out_file, get_frame_size ());
 
   /* And debug output.  */
   (*debug_hooks->end_epilogue) (last_linenum, last_filename);
 
   /* And debug output.  */
   (*debug_hooks->end_epilogue) (last_linenum, last_filename);
@@ -1534,63 +1501,49 @@ final_end_function ()
    Prescanning is done only on certain machines.  */
 
 void
    Prescanning is done only on certain machines.  */
 
 void
-final (first, file, optimize, prescan)
-     rtx first;
-     FILE *file;
-     int optimize;
-     int prescan;
+final (rtx first, FILE *file, int optimize, int prescan)
 {
   rtx insn;
 {
   rtx insn;
-  int max_line = 0;
   int max_uid = 0;
   int max_uid = 0;
+  int seen = 0;
 
   last_ignored_compare = 0;
 
 
   last_ignored_compare = 0;
 
-  /* Make a map indicating which line numbers appear in this function.
-     When producing SDB debugging info, delete troublesome line number
+#ifdef SDB_DEBUGGING_INFO
+  /* When producing SDB debugging info, delete troublesome line number
      notes from inlined functions in other files as well as duplicate
      line number notes.  */
      notes from inlined functions in other files as well as duplicate
      line number notes.  */
-#ifdef SDB_DEBUGGING_INFO
   if (write_symbols == SDB_DEBUG)
     {
       rtx last = 0;
       for (insn = first; insn; insn = NEXT_INSN (insn))
   if (write_symbols == SDB_DEBUG)
     {
       rtx last = 0;
       for (insn = first; insn; insn = NEXT_INSN (insn))
-       if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
+       if (NOTE_P (insn) && NOTE_LINE_NUMBER (insn) > 0)
          {
          {
-           if ((RTX_INTEGRATED_P (insn)
-                && strcmp (NOTE_SOURCE_FILE (insn), main_input_filename) != 0)
-                || (last != 0
-                    && NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last)
-                    && NOTE_SOURCE_FILE (insn) == NOTE_SOURCE_FILE (last)))
+           if (last != 0
+#ifdef USE_MAPPED_LOCATION
+               && NOTE_SOURCE_LOCATION (insn) == NOTE_SOURCE_LOCATION (last)
+#else
+               && NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last)
+               && NOTE_SOURCE_FILE (insn) == NOTE_SOURCE_FILE (last)
+#endif
+             )
              {
                delete_insn (insn);     /* Use delete_note.  */
                continue;
              }
            last = insn;
              {
                delete_insn (insn);     /* Use delete_note.  */
                continue;
              }
            last = insn;
-           if (NOTE_LINE_NUMBER (insn) > max_line)
-             max_line = NOTE_LINE_NUMBER (insn);
          }
     }
          }
     }
-  else
 #endif
 #endif
-    {
-      for (insn = first; insn; insn = NEXT_INSN (insn))
-       if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > max_line)
-         max_line = NOTE_LINE_NUMBER (insn);
-    }
-
-  line_note_exists = (char *) xcalloc (max_line + 1, sizeof (char));
 
   for (insn = first; insn; insn = NEXT_INSN (insn))
     {
 
   for (insn = first; insn; insn = NEXT_INSN (insn))
     {
-      if (INSN_UID (insn) > max_uid)       /* find largest UID */
+      if (INSN_UID (insn) > max_uid)       /* Find largest UID.  */
        max_uid = INSN_UID (insn);
        max_uid = INSN_UID (insn);
-      if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
-       line_note_exists[NOTE_LINE_NUMBER (insn)] = 1;
 #ifdef HAVE_cc0
       /* If CC tracking across branches is enabled, record the insn which
         jumps to each branch only reached from one place.  */
 #ifdef HAVE_cc0
       /* If CC tracking across branches is enabled, record the insn which
         jumps to each branch only reached from one place.  */
-      if (optimize && GET_CODE (insn) == JUMP_INSN)
+      if (optimize && JUMP_P (insn))
        {
          rtx lab = JUMP_LABEL (insn);
          if (lab && LABEL_NUSES (lab) == 1)
        {
          rtx lab = JUMP_LABEL (insn);
          if (lab && LABEL_NUSES (lab) == 1)
@@ -1613,41 +1566,32 @@ final (first, file, optimize, prescan)
        {
          /* This can be triggered by bugs elsewhere in the compiler if
             new insns are created after init_insn_lengths is called.  */
        {
          /* This can be triggered by bugs elsewhere in the compiler if
             new insns are created after init_insn_lengths is called.  */
-         if (GET_CODE (insn) == NOTE)
-           insn_current_address = -1;
-         else
-           abort ();
+         gcc_assert (NOTE_P (insn));
+         insn_current_address = -1;
        }
       else
        insn_current_address = INSN_ADDRESSES (INSN_UID (insn));
 #endif /* HAVE_ATTR_length */
 
        }
       else
        insn_current_address = INSN_ADDRESSES (INSN_UID (insn));
 #endif /* HAVE_ATTR_length */
 
-      insn = final_scan_insn (insn, file, optimize, prescan, 0);
+      insn = final_scan_insn (insn, file, optimize, prescan, 0, &seen);
     }
     }
-
-  free (line_note_exists);
-  line_note_exists = NULL;
 }
 \f
 const char *
 }
 \f
 const char *
-get_insn_template (code, insn)
-     int code;
-     rtx insn;
+get_insn_template (int code, rtx insn)
 {
 {
-  const void *output = insn_data[code].output;
   switch (insn_data[code].output_format)
     {
     case INSN_OUTPUT_FORMAT_SINGLE:
   switch (insn_data[code].output_format)
     {
     case INSN_OUTPUT_FORMAT_SINGLE:
-      return (const char *) output;
+      return insn_data[code].output.single;
     case INSN_OUTPUT_FORMAT_MULTI:
     case INSN_OUTPUT_FORMAT_MULTI:
-      return ((const char *const *) output)[which_alternative];
+      return insn_data[code].output.multi[which_alternative];
     case INSN_OUTPUT_FORMAT_FUNCTION:
     case INSN_OUTPUT_FORMAT_FUNCTION:
-      if (insn == NULL)
-       abort ();
-      return (*(insn_output_fn) output) (recog_data.operand, insn);
+      gcc_assert (insn);
+      return (*insn_data[code].output.function) (recog_data.operand, insn);
 
     default:
 
     default:
-      abort ();
+      gcc_unreachable ();
     }
 }
 
     }
 }
 
@@ -1657,9 +1601,7 @@ get_insn_template (code, insn)
 
    The case fall-through in this function is intentional.  */
 static void
 
    The case fall-through in this function is intentional.  */
 static void
-output_alternate_entry_point (file, insn)
-     FILE *file;
-     rtx insn;
+output_alternate_entry_point (FILE *file, rtx insn)
 {
   const char *name = LABEL_NAME (insn);
 
 {
   const char *name = LABEL_NAME (insn);
 
@@ -1670,7 +1612,7 @@ output_alternate_entry_point (file, insn)
       ASM_WEAKEN_LABEL (file, name);
 #endif
     case LABEL_GLOBAL_ENTRY:
       ASM_WEAKEN_LABEL (file, name);
 #endif
     case LABEL_GLOBAL_ENTRY:
-      (*targetm.asm_out.globalize_label) (file, name);
+      targetm.asm_out.globalize_label (file, name);
     case LABEL_STATIC_ENTRY:
 #ifdef ASM_OUTPUT_TYPE_DIRECTIVE
       ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
     case LABEL_STATIC_ENTRY:
 #ifdef ASM_OUTPUT_TYPE_DIRECTIVE
       ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
@@ -1680,8 +1622,37 @@ output_alternate_entry_point (file, insn)
 
     case LABEL_NORMAL:
     default:
 
     case LABEL_NORMAL:
     default:
-      abort ();
+      gcc_unreachable ();
+    }
+}
+
+/* Return boolean indicating if there is a NOTE_INSN_UNLIKELY_EXECUTED_CODE
+   note in the instruction chain (going forward) between the current
+   instruction, and the next 'executable' instruction.  */
+
+bool
+scan_ahead_for_unlikely_executed_note (rtx insn)
+{
+  rtx temp;
+  int bb_note_count = 0;
+
+  for (temp = insn; temp; temp = NEXT_INSN (temp))
+    {
+      if (NOTE_P (temp)
+         && NOTE_LINE_NUMBER (temp) == NOTE_INSN_UNLIKELY_EXECUTED_CODE)
+       return true;
+      if (NOTE_P (temp)
+         && NOTE_LINE_NUMBER (temp) == NOTE_INSN_BASIC_BLOCK)
+       {
+         bb_note_count++;
+         if (bb_note_count > 1)
+           return false;
+       }
+      if (INSN_P (temp))
+       return false;
     }
     }
+  
+  return false;
 }
 
 /* The final scan for one insn, INSN.
 }
 
 /* The final scan for one insn, INSN.
@@ -1690,15 +1661,18 @@ output_alternate_entry_point (file, insn)
    Value returned is the next insn to be scanned.
 
    NOPEEPHOLES is the flag to disallow peephole processing (currently
    Value returned is the next insn to be scanned.
 
    NOPEEPHOLES is the flag to disallow peephole processing (currently
-   used for within delayed branch sequence output).  */
+   used for within delayed branch sequence output).
+
+   SEEN is used to track the end of the prologue, for emitting
+   debug information.  We force the emission of a line note after
+   both NOTE_INSN_PROLOGUE_END and NOTE_INSN_FUNCTION_BEG, or
+   at the beginning of the second basic block, whichever comes
+   first.  */
 
 rtx
 
 rtx
-final_scan_insn (insn, file, optimize, prescan, nopeepholes)
-     rtx insn;
-     FILE *file;
-     int optimize ATTRIBUTE_UNUSED;
-     int prescan;
-     int nopeepholes ATTRIBUTE_UNUSED;
+final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
+                int prescan, int nopeepholes ATTRIBUTE_UNUSED,
+                int *seen)
 {
 #ifdef HAVE_cc0
   rtx set;
 {
 #ifdef HAVE_cc0
   rtx set;
@@ -1722,21 +1696,51 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
        case NOTE_INSN_DELETED:
        case NOTE_INSN_LOOP_BEG:
        case NOTE_INSN_LOOP_END:
        case NOTE_INSN_DELETED:
        case NOTE_INSN_LOOP_BEG:
        case NOTE_INSN_LOOP_END:
-       case NOTE_INSN_LOOP_END_TOP_COND:
-       case NOTE_INSN_LOOP_CONT:
-       case NOTE_INSN_LOOP_VTOP:
        case NOTE_INSN_FUNCTION_END:
        case NOTE_INSN_REPEATED_LINE_NUMBER:
        case NOTE_INSN_EXPECTED_VALUE:
          break;
 
        case NOTE_INSN_FUNCTION_END:
        case NOTE_INSN_REPEATED_LINE_NUMBER:
        case NOTE_INSN_EXPECTED_VALUE:
          break;
 
+       case NOTE_INSN_UNLIKELY_EXECUTED_CODE:
+         
+         /* The presence of this note indicates that this basic block
+            belongs in the "cold" section of the .o file.  If we are
+            not already writing to the cold section we need to change
+            to it.  */
+         
+         unlikely_text_section ();
+         break;
+         
        case NOTE_INSN_BASIC_BLOCK:
        case NOTE_INSN_BASIC_BLOCK:
-#ifdef IA64_UNWIND_INFO
-         IA64_UNWIND_EMIT (asm_out_file, insn);
+         
+         /* If we are performing the optimization that partitions
+            basic blocks into hot & cold sections of the .o file,
+            then at the start of each new basic block, before
+            beginning to write code for the basic block, we need to
+            check to see whether the basic block belongs in the hot
+            or cold section of the .o file, and change the section we
+            are writing to appropriately.  */
+         
+         if (flag_reorder_blocks_and_partition
+             && !scan_ahead_for_unlikely_executed_note (insn))
+           function_section (current_function_decl);
+
+#ifdef TARGET_UNWIND_INFO
+         targetm.asm_out.unwind_emit (asm_out_file, insn);
 #endif
 #endif
+
          if (flag_debug_asm)
            fprintf (asm_out_file, "\t%s basic block %d\n",
                     ASM_COMMENT_START, NOTE_BASIC_BLOCK (insn)->index);
          if (flag_debug_asm)
            fprintf (asm_out_file, "\t%s basic block %d\n",
                     ASM_COMMENT_START, NOTE_BASIC_BLOCK (insn)->index);
+
+         if ((*seen & (SEEN_EMITTED | SEEN_BB)) == SEEN_BB)
+           {
+             *seen |= SEEN_EMITTED;
+             last_filename = NULL;
+           }
+         else
+           *seen |= SEEN_BB;
+
          break;
 
        case NOTE_INSN_EH_REGION_BEG:
          break;
 
        case NOTE_INSN_EH_REGION_BEG:
@@ -1750,23 +1754,40 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
          break;
 
        case NOTE_INSN_PROLOGUE_END:
          break;
 
        case NOTE_INSN_PROLOGUE_END:
-         (*targetm.asm_out.function_end_prologue) (file);
+         targetm.asm_out.function_end_prologue (file);
          profile_after_prologue (file);
          profile_after_prologue (file);
+
+         if ((*seen & (SEEN_EMITTED | SEEN_NOTE)) == SEEN_NOTE)
+           {
+             *seen |= SEEN_EMITTED;
+             last_filename = NULL;
+           }
+         else
+           *seen |= SEEN_NOTE;
+
          break;
 
        case NOTE_INSN_EPILOGUE_BEG:
          break;
 
        case NOTE_INSN_EPILOGUE_BEG:
-         (*targetm.asm_out.function_begin_epilogue) (file);
+         targetm.asm_out.function_begin_epilogue (file);
          break;
 
        case NOTE_INSN_FUNCTION_BEG:
          app_disable ();
          (*debug_hooks->end_prologue) (last_linenum, last_filename);
          break;
 
        case NOTE_INSN_FUNCTION_BEG:
          app_disable ();
          (*debug_hooks->end_prologue) (last_linenum, last_filename);
+
+         if ((*seen & (SEEN_EMITTED | SEEN_NOTE)) == SEEN_NOTE)
+           {
+             *seen |= SEEN_EMITTED;
+             last_filename = NULL;
+           }
+         else
+           *seen |= SEEN_NOTE;
+
          break;
 
        case NOTE_INSN_BLOCK_BEG:
          if (debug_info_level == DINFO_LEVEL_NORMAL
              || debug_info_level == DINFO_LEVEL_VERBOSE
          break;
 
        case NOTE_INSN_BLOCK_BEG:
          if (debug_info_level == DINFO_LEVEL_NORMAL
              || debug_info_level == DINFO_LEVEL_VERBOSE
-             || write_symbols == DWARF_DEBUG
              || write_symbols == DWARF2_DEBUG
              || write_symbols == VMS_AND_DWARF2_DEBUG
              || write_symbols == VMS_DEBUG)
              || write_symbols == DWARF2_DEBUG
              || write_symbols == VMS_AND_DWARF2_DEBUG
              || write_symbols == VMS_DEBUG)
@@ -1788,7 +1809,6 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
        case NOTE_INSN_BLOCK_END:
          if (debug_info_level == DINFO_LEVEL_NORMAL
              || debug_info_level == DINFO_LEVEL_VERBOSE
        case NOTE_INSN_BLOCK_END:
          if (debug_info_level == DINFO_LEVEL_NORMAL
              || debug_info_level == DINFO_LEVEL_VERBOSE
-             || write_symbols == DWARF_DEBUG
              || write_symbols == DWARF2_DEBUG
              || write_symbols == VMS_AND_DWARF2_DEBUG
              || write_symbols == VMS_DEBUG)
              || write_symbols == DWARF2_DEBUG
              || write_symbols == VMS_AND_DWARF2_DEBUG
              || write_symbols == VMS_DEBUG)
@@ -1799,8 +1819,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
 
              /* End of a symbol-block.  */
              --block_depth;
 
              /* End of a symbol-block.  */
              --block_depth;
-             if (block_depth < 0)
-               abort ();
+             gcc_assert (block_depth >= 0);
 
              (*debug_hooks->end_block) (high_block_linenum, n);
            }
 
              (*debug_hooks->end_block) (high_block_linenum, n);
            }
@@ -1813,57 +1832,15 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
          ASM_OUTPUT_DEBUG_LABEL (file, "L", CODE_LABEL_NUMBER (insn));
          break;
 
          ASM_OUTPUT_DEBUG_LABEL (file, "L", CODE_LABEL_NUMBER (insn));
          break;
 
+       case NOTE_INSN_VAR_LOCATION:
+         (*debug_hooks->var_location) (insn);
+         break;
+
        case 0:
          break;
 
        default:
        case 0:
          break;
 
        default:
-         if (NOTE_LINE_NUMBER (insn) <= 0)
-           abort ();
-
-         /* This note is a line-number.  */
-         {
-           rtx note;
-           int note_after = 0;
-
-           /* If there is anything real after this note, output it.
-              If another line note follows, omit this one.  */
-           for (note = NEXT_INSN (insn); note; note = NEXT_INSN (note))
-             {
-               if (GET_CODE (note) != NOTE && GET_CODE (note) != CODE_LABEL)
-                 break;
-
-               /* These types of notes can be significant
-                  so make sure the preceding line number stays.  */
-               else if (GET_CODE (note) == NOTE
-                        && (NOTE_LINE_NUMBER (note) == NOTE_INSN_BLOCK_BEG
-                            || NOTE_LINE_NUMBER (note) == NOTE_INSN_BLOCK_END
-                            || NOTE_LINE_NUMBER (note) == NOTE_INSN_FUNCTION_BEG))
-                 break;
-               else if (GET_CODE (note) == NOTE && NOTE_LINE_NUMBER (note) > 0)
-                 {
-                   /* Another line note follows; we can delete this note
-                      if no intervening line numbers have notes elsewhere.  */
-                   int num;
-                   for (num = NOTE_LINE_NUMBER (insn) + 1;
-                        num < NOTE_LINE_NUMBER (note);
-                        num++)
-                     if (line_note_exists[num])
-                       break;
-
-                   if (num >= NOTE_LINE_NUMBER (note))
-                     note_after = 1;
-                   break;
-                 }
-             }
-
-           /* Output this line note if it is the first or the last line
-              note in a row.  */
-           if (!note_after)
-             {
-               notice_source_line (insn);
-               (*debug_hooks->source_line) (last_linenum, last_filename);
-             }
-         }
+         gcc_assert (NOTE_LINE_NUMBER (insn) > 0);
          break;
        }
       break;
          break;
        }
       break;
@@ -1871,7 +1848,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
     case BARRIER:
 #if defined (DWARF2_UNWIND_INFO)
       if (dwarf2out_do_frame ())
     case BARRIER:
 #if defined (DWARF2_UNWIND_INFO)
       if (dwarf2out_do_frame ())
-       dwarf2out_frame_debug (insn);
+       dwarf2out_frame_debug (insn, false);
 #endif
       break;
 
 #endif
       break;
 
@@ -1915,10 +1892,10 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
             insn, and that branch is the only way to reach this label,
             set the condition codes based on the branch and its
             predecessor.  */
             insn, and that branch is the only way to reach this label,
             set the condition codes based on the branch and its
             predecessor.  */
-         if (barrier && GET_CODE (barrier) == BARRIER
-             && jump && GET_CODE (jump) == JUMP_INSN
+         if (barrier && BARRIER_P (barrier)
+             && jump && JUMP_P (jump)
              && (prev = prev_nonnote_insn (jump))
              && (prev = prev_nonnote_insn (jump))
-             && GET_CODE (prev) == INSN)
+             && NONJUMP_INSN_P (prev))
            {
              NOTICE_UPDATE_CC (PATTERN (prev), prev);
              NOTICE_UPDATE_CC (PATTERN (jump), jump);
            {
              NOTICE_UPDATE_CC (PATTERN (prev), prev);
              NOTICE_UPDATE_CC (PATTERN (jump), jump);
@@ -1928,20 +1905,35 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
       if (prescan > 0)
        break;
 
       if (prescan > 0)
        break;
 
-#ifdef FINAL_PRESCAN_LABEL
-      FINAL_PRESCAN_INSN (insn, NULL, 0);
-#endif
-
       if (LABEL_NAME (insn))
        (*debug_hooks->label) (insn);
 
       if (LABEL_NAME (insn))
        (*debug_hooks->label) (insn);
 
+      /* If we are doing the optimization that partitions hot & cold
+        basic blocks into separate sections of the .o file, we need
+        to ensure the jump table ends up in the correct section...  */
+      
+      if (flag_reorder_blocks_and_partition
+         && targetm.have_named_sections)
+       {
+         rtx tmp_table, tmp_label;
+         if (LABEL_P (insn)
+             && tablejump_p (NEXT_INSN (insn), &tmp_label, &tmp_table))
+           {
+             /* Do nothing; Do NOT change the current section.  */
+           }
+         else if (scan_ahead_for_unlikely_executed_note (insn)) 
+           unlikely_text_section ();
+         else if (in_unlikely_text_section ())
+           function_section (current_function_decl);
+       }
+
       if (app_on)
        {
          fputs (ASM_APP_OFF, file);
          app_on = 0;
        }
       if (NEXT_INSN (insn) != 0
       if (app_on)
        {
          fputs (ASM_APP_OFF, file);
          app_on = 0;
        }
       if (NEXT_INSN (insn) != 0
-         && GET_CODE (NEXT_INSN (insn)) == JUMP_INSN)
+         && JUMP_P (NEXT_INSN (insn)))
        {
          rtx nextbody = PATTERN (NEXT_INSN (insn));
 
        {
          rtx nextbody = PATTERN (NEXT_INSN (insn));
 
@@ -1961,7 +1953,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
                {
                  int log_align;
 
                {
                  int log_align;
 
-                 readonly_data_section ();
+                 targetm.asm_out.function_rodata_section (current_function_decl);
 
 #ifdef ADDR_VEC_ALIGN
                  log_align = ADDR_VEC_ALIGN (NEXT_INSN (insn));
 
 #ifdef ADDR_VEC_ALIGN
                  log_align = ADDR_VEC_ALIGN (NEXT_INSN (insn));
@@ -1977,7 +1969,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
              ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
                                     NEXT_INSN (insn));
 #else
              ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
                                     NEXT_INSN (insn));
 #else
-             (*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (insn));
+             targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
 #endif
 #endif
              break;
 #endif
 #endif
              break;
@@ -1986,7 +1978,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
       if (LABEL_ALT_ENTRY_P (insn))
        output_alternate_entry_point (file, insn);
       else
       if (LABEL_ALT_ENTRY_P (insn))
        output_alternate_entry_point (file, insn);
       else
-       (*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (insn));
+       targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
       break;
 
     default:
       break;
 
     default:
@@ -1994,27 +1986,28 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
        rtx body = PATTERN (insn);
        int insn_code_number;
        const char *template;
        rtx body = PATTERN (insn);
        int insn_code_number;
        const char *template;
-       rtx note;
 
        /* An INSN, JUMP_INSN or CALL_INSN.
           First check for special kinds that recog doesn't recognize.  */
 
 
        /* An INSN, JUMP_INSN or CALL_INSN.
           First check for special kinds that recog doesn't recognize.  */
 
-       if (GET_CODE (body) == USE /* These are just declarations */
+       if (GET_CODE (body) == USE /* These are just declarations */
            || GET_CODE (body) == CLOBBER)
          break;
 
 #ifdef HAVE_cc0
            || GET_CODE (body) == CLOBBER)
          break;
 
 #ifdef HAVE_cc0
-       /* If there is a REG_CC_SETTER note on this insn, it means that
-          the setting of the condition code was done in the delay slot
-          of the insn that branched here.  So recover the cc status
-          from the insn that set it.  */
+       {
+         /* If there is a REG_CC_SETTER note on this insn, it means that
+            the setting of the condition code was done in the delay slot
+            of the insn that branched here.  So recover the cc status
+            from the insn that set it.  */
 
 
-       note = find_reg_note (insn, REG_CC_SETTER, NULL_RTX);
-       if (note)
-         {
-           NOTICE_UPDATE_CC (PATTERN (XEXP (note, 0)), XEXP (note, 0));
-           cc_prev_status = cc_status;
-         }
+         rtx note = find_reg_note (insn, REG_CC_SETTER, NULL_RTX);
+         if (note)
+           {
+             NOTICE_UPDATE_CC (PATTERN (XEXP (note, 0)), XEXP (note, 0));
+             cc_prev_status = cc_status;
+           }
+       }
 #endif
 
        /* Detect insns that are really jump-tables
 #endif
 
        /* Detect insns that are really jump-tables
@@ -2041,7 +2034,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
 #ifdef ASM_OUTPUT_ADDR_VEC
                ASM_OUTPUT_ADDR_VEC (PREV_INSN (insn), body);
 #else
 #ifdef ASM_OUTPUT_ADDR_VEC
                ASM_OUTPUT_ADDR_VEC (PREV_INSN (insn), body);
 #else
-               abort ();
+               gcc_unreachable ();
 #endif
              }
            else
 #endif
              }
            else
@@ -2049,7 +2042,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
 #ifdef ASM_OUTPUT_ADDR_DIFF_VEC
                ASM_OUTPUT_ADDR_DIFF_VEC (PREV_INSN (insn), body);
 #else
 #ifdef ASM_OUTPUT_ADDR_DIFF_VEC
                ASM_OUTPUT_ADDR_DIFF_VEC (PREV_INSN (insn), body);
 #else
-               abort ();
+               gcc_unreachable ();
 #endif
              }
 #else
 #endif
              }
 #else
@@ -2062,7 +2055,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
                    ASM_OUTPUT_ADDR_VEC_ELT
                      (file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0)));
 #else
                    ASM_OUTPUT_ADDR_VEC_ELT
                      (file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0)));
 #else
-                   abort ();
+                   gcc_unreachable ();
 #endif
                  }
                else
 #endif
                  }
                else
@@ -2074,7 +2067,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
                       CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 1, idx), 0)),
                       CODE_LABEL_NUMBER (XEXP (XEXP (body, 0), 0)));
 #else
                       CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 1, idx), 0)),
                       CODE_LABEL_NUMBER (XEXP (XEXP (body, 0), 0)));
 #else
-                   abort ();
+                   gcc_unreachable ();
 #endif
                  }
              }
 #endif
                  }
              }
@@ -2089,6 +2082,12 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
 
            break;
          }
 
            break;
          }
+       /* Output this line note if it is the first or the last line
+          note in a row.  */
+       if (notice_source_line (insn))
+         {
+           (*debug_hooks->source_line) (last_linenum, last_filename);
+         }
 
        if (GET_CODE (body) == ASM_INPUT)
          {
 
        if (GET_CODE (body) == ASM_INPUT)
          {
@@ -2115,7 +2114,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
        if (asm_noperands (body) >= 0)
          {
            unsigned int noperands = asm_noperands (body);
        if (asm_noperands (body) >= 0)
          {
            unsigned int noperands = asm_noperands (body);
-           rtx *ops = (rtx *) alloca (noperands * sizeof (rtx));
+           rtx *ops = alloca (noperands * sizeof (rtx));
            const char *string;
 
            /* There's no telling what that did to the condition codes.  */
            const char *string;
 
            /* There's no telling what that did to the condition codes.  */
@@ -2129,6 +2128,10 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
            insn_noperands = noperands;
            this_is_asm_operands = insn;
 
            insn_noperands = noperands;
            this_is_asm_operands = insn;
 
+#ifdef FINAL_PRESCAN_INSN
+           FINAL_PRESCAN_INSN (insn, ops, insn_noperands);
+#endif
+
            /* Output the insn using them.  */
            if (string[0])
              {
            /* Output the insn using them.  */
            if (string[0])
              {
@@ -2160,12 +2163,20 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
              break;
            final_sequence = body;
 
              break;
            final_sequence = body;
 
+           /* Record the delay slots' frame information before the branch.
+              This is needed for delayed calls: see execute_cfa_program().  */
+#if defined (DWARF2_UNWIND_INFO)
+           if (dwarf2out_do_frame ())
+             for (i = 1; i < XVECLEN (body, 0); i++)
+               dwarf2out_frame_debug (XVECEXP (body, 0, i), false);
+#endif
+
            /* The first insn in this SEQUENCE might be a JUMP_INSN that will
               force the restoration of a comparison that was previously
               thought unnecessary.  If that happens, cancel this sequence
               and cause that insn to be restored.  */
 
            /* The first insn in this SEQUENCE might be a JUMP_INSN that will
               force the restoration of a comparison that was previously
               thought unnecessary.  If that happens, cancel this sequence
               and cause that insn to be restored.  */
 
-           next = final_scan_insn (XVECEXP (body, 0, 0), file, 0, prescan, 1);
+           next = final_scan_insn (XVECEXP (body, 0, 0), file, 0, prescan, 1, seen);
            if (next != XVECEXP (body, 0, 1))
              {
                final_sequence = 0;
            if (next != XVECEXP (body, 0, 1))
              {
                final_sequence = 0;
@@ -2179,7 +2190,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
                /* We loop in case any instruction in a delay slot gets
                   split.  */
                do
                /* We loop in case any instruction in a delay slot gets
                   split.  */
                do
-                 insn = final_scan_insn (insn, file, 0, prescan, 1);
+                 insn = final_scan_insn (insn, file, 0, prescan, 1, seen);
                while (insn != next);
              }
 #ifdef DBR_OUTPUT_SEQEND
                while (insn != next);
              }
 #ifdef DBR_OUTPUT_SEQEND
@@ -2192,7 +2203,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
               called function.  Hence we don't preserve any CC-setting
               actions in these insns and the CC must be marked as being
               clobbered by the function.  */
               called function.  Hence we don't preserve any CC-setting
               actions in these insns and the CC must be marked as being
               clobbered by the function.  */
-           if (GET_CODE (XVECEXP (body, 0, 0)) == CALL_INSN)
+           if (CALL_P (XVECEXP (body, 0, 0)))
              {
                CC_STATUS_INIT;
              }
              {
                CC_STATUS_INIT;
              }
@@ -2216,10 +2227,6 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
 
        if (optimize)
          {
 
        if (optimize)
          {
-#if 0
-           rtx set = single_set (insn);
-#endif
-
            if (set
                && GET_CODE (SET_DEST (set)) == CC0
                && insn != last_ignored_compare)
            if (set
                && GET_CODE (SET_DEST (set)) == CC0
                && insn != last_ignored_compare)
@@ -2261,9 +2268,9 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
           will cause an improper number of delay insns to be written.  */
        if (final_sequence == 0
            && prescan >= 0
           will cause an improper number of delay insns to be written.  */
        if (final_sequence == 0
            && prescan >= 0
-           && GET_CODE (insn) == INSN && GET_CODE (body) == SET
-           && GET_CODE (SET_SRC (body)) == REG
-           && GET_CODE (SET_DEST (body)) == REG
+           && NONJUMP_INSN_P (insn) && GET_CODE (body) == SET
+           && REG_P (SET_SRC (body))
+           && REG_P (SET_DEST (body))
            && REGNO (SET_SRC (body)) == REGNO (SET_DEST (body)))
          break;
 #endif
            && REGNO (SET_SRC (body)) == REGNO (SET_DEST (body)))
          break;
 #endif
@@ -2275,11 +2282,11 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
           do straightforwardly if the cc's were set up normally.  */
 
        if (cc_status.flags != 0
           do straightforwardly if the cc's were set up normally.  */
 
        if (cc_status.flags != 0
-           && GET_CODE (insn) == JUMP_INSN
+           && JUMP_P (insn)
            && GET_CODE (body) == SET
            && SET_DEST (body) == pc_rtx
            && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE
            && GET_CODE (body) == SET
            && SET_DEST (body) == pc_rtx
            && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE
-           && GET_RTX_CLASS (GET_CODE (XEXP (SET_SRC (body), 0))) == '<'
+           && COMPARISON_P (XEXP (SET_SRC (body), 0))
            && XEXP (XEXP (SET_SRC (body), 0), 0) == cc0_rtx
            /* This is done during prescan; it is not done again
               in final scan when prescan has been done.  */
            && XEXP (XEXP (SET_SRC (body), 0), 0) == cc0_rtx
            /* This is done during prescan; it is not done again
               in final scan when prescan has been done.  */
@@ -2324,7 +2331,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
          {
            rtx cond_rtx, then_rtx, else_rtx;
 
          {
            rtx cond_rtx, then_rtx, else_rtx;
 
-           if (GET_CODE (insn) != JUMP_INSN
+           if (!JUMP_P (insn)
                && GET_CODE (SET_SRC (set)) == IF_THEN_ELSE)
              {
                cond_rtx = XEXP (SET_SRC (set), 0);
                && GET_CODE (SET_SRC (set)) == IF_THEN_ELSE)
              {
                cond_rtx = XEXP (SET_SRC (set), 0);
@@ -2383,11 +2390,11 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
               emit them before the peephole.  */
            if (next != 0 && next != NEXT_INSN (insn))
              {
               emit them before the peephole.  */
            if (next != 0 && next != NEXT_INSN (insn))
              {
-               rtx prev = PREV_INSN (insn);
+               rtx note, prev = PREV_INSN (insn);
 
                for (note = NEXT_INSN (insn); note != next;
                     note = NEXT_INSN (note))
 
                for (note = NEXT_INSN (insn); note != next;
                     note = NEXT_INSN (note))
-                 final_scan_insn (note, file, optimize, prescan, nopeepholes);
+                 final_scan_insn (note, file, optimize, prescan, nopeepholes, seen);
 
                /* In case this is prescan, put the notes
                   in proper position for later rescan.  */
 
                /* In case this is prescan, put the notes
                   in proper position for later rescan.  */
@@ -2452,8 +2459,8 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
        current_output_insn = debug_insn = insn;
 
 #if defined (DWARF2_UNWIND_INFO)
        current_output_insn = debug_insn = insn;
 
 #if defined (DWARF2_UNWIND_INFO)
-       if (GET_CODE (insn) == CALL_INSN && dwarf2out_do_frame ())
-         dwarf2out_frame_debug (insn);
+       if (CALL_P (insn) && dwarf2out_do_frame ())
+         dwarf2out_frame_debug (insn, false);
 #endif
 
        /* Find the proper template for this insn.  */
 #endif
 
        /* Find the proper template for this insn.  */
@@ -2466,8 +2473,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
          {
            rtx prev;
 
          {
            rtx prev;
 
-           if (prev_nonnote_insn (insn) != last_ignored_compare)
-             abort ();
+           gcc_assert (prev_nonnote_insn (insn) == last_ignored_compare);
 
            /* We have already processed the notes between the setter and
               the user.  Make sure we don't process them again, this is
 
            /* We have already processed the notes between the setter and
               the user.  Make sure we don't process them again, this is
@@ -2477,7 +2483,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
                 prev != last_ignored_compare;
                 prev = PREV_INSN (prev))
              {
                 prev != last_ignored_compare;
                 prev = PREV_INSN (prev))
              {
-               if (GET_CODE (prev) == NOTE)
+               if (NOTE_P (prev))
                  delete_insn (prev);   /* Use delete_note.  */
              }
 
                  delete_insn (prev);   /* Use delete_note.  */
              }
 
@@ -2498,7 +2504,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
            /* This instruction should have been split in shorten_branches,
               to ensure that we would have valid length info for the
               splitees.  */
            /* This instruction should have been split in shorten_branches,
               to ensure that we would have valid length info for the
               splitees.  */
-           abort ();
+           gcc_unreachable ();
 #endif
 
            return new;
 #endif
 
            return new;
@@ -2507,40 +2513,28 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
        if (prescan > 0)
          break;
 
        if (prescan > 0)
          break;
 
-#ifdef IA64_UNWIND_INFO
-       IA64_UNWIND_EMIT (asm_out_file, insn);
+#ifdef TARGET_UNWIND_INFO
+       /* ??? This will put the directives in the wrong place if
+          get_insn_template outputs assembly directly.  However calling it
+          before get_insn_template breaks if the insns is split.  */
+       targetm.asm_out.unwind_emit (asm_out_file, insn);
 #endif
 #endif
-       /* Output assembler code from the template.  */
 
 
+       /* Output assembler code from the template.  */
        output_asm_insn (template, recog_data.operand);
 
        output_asm_insn (template, recog_data.operand);
 
+       /* If necessary, report the effect that the instruction has on
+          the unwind info.   We've already done this for delay slots
+          and call instructions.  */
 #if defined (DWARF2_UNWIND_INFO)
 #if defined (DWARF2_UNWIND_INFO)
-#if defined (HAVE_prologue)
-       if (GET_CODE (insn) == INSN && dwarf2out_do_frame ())
-         dwarf2out_frame_debug (insn);
-#else
-       if (!ACCUMULATE_OUTGOING_ARGS
-           && GET_CODE (insn) == INSN
-           && dwarf2out_do_frame ())
-         dwarf2out_frame_debug (insn);
-#endif
+       if (final_sequence == 0
+#if !defined (HAVE_prologue)
+           && !ACCUMULATE_OUTGOING_ARGS
 #endif
 #endif
-
-#if 0
-       /* It's not at all clear why we did this and doing so interferes
-          with tests we'd like to do to use REG_WAS_0 notes, so let's try
-          with this out.  */
-
-       /* Mark this insn as having been output.  */
-       INSN_DELETED_P (insn) = 1;
+           && dwarf2out_do_frame ())
+         dwarf2out_frame_debug (insn, true);
 #endif
 
 #endif
 
-       /* Emit information for vtable gc.  */
-       note = find_reg_note (insn, REG_VTABLE_REF, NULL_RTX);
-       if (note)
-         assemble_vtable_entry (XEXP (XEXP (note, 0), 0),
-                                INTVAL (XEXP (XEXP (note, 0), 1)));
-
        current_output_insn = debug_insn = 0;
       }
     }
        current_output_insn = debug_insn = 0;
       }
     }
@@ -2550,30 +2544,34 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
 /* Output debugging info to the assembler file FILE
    based on the NOTE-insn INSN, assumed to be a line number.  */
 
 /* Output debugging info to the assembler file FILE
    based on the NOTE-insn INSN, assumed to be a line number.  */
 
-static void
-notice_source_line (insn)
-     rtx insn;
+static bool
+notice_source_line (rtx insn)
 {
 {
-  const char *filename = NOTE_SOURCE_FILE (insn);
+  const char *filename = insn_file (insn);
+  int linenum = insn_line (insn);
 
 
-  last_filename = filename;
-  last_linenum = NOTE_LINE_NUMBER (insn);
-  high_block_linenum = MAX (last_linenum, high_block_linenum);
-  high_function_linenum = MAX (last_linenum, high_function_linenum);
+  if (filename && (filename != last_filename || last_linenum != linenum))
+    {
+      last_filename = filename;
+      last_linenum = linenum;
+      high_block_linenum = MAX (last_linenum, high_block_linenum);
+      high_function_linenum = MAX (last_linenum, high_function_linenum);
+      return true;
+    }
+  return false;
 }
 \f
 /* For each operand in INSN, simplify (subreg (reg)) so that it refers
    directly to the desired hard register.  */
 
 void
 }
 \f
 /* For each operand in INSN, simplify (subreg (reg)) so that it refers
    directly to the desired hard register.  */
 
 void
-cleanup_subreg_operands (insn)
-     rtx insn;
+cleanup_subreg_operands (rtx insn)
 {
   int i;
   extract_insn_cached (insn);
   for (i = 0; i < recog_data.n_operands; i++)
     {
 {
   int i;
   extract_insn_cached (insn);
   for (i = 0; i < recog_data.n_operands; i++)
     {
-      /* The following test cannot use recog_data.operand when tesing
+      /* The following test cannot use recog_data.operand when testing
         for a SUBREG: the underlying object might have been changed
         already if we are inside a match_operator expression that
         matches the else clause.  Instead we test the underlying
         for a SUBREG: the underlying object might have been changed
         already if we are inside a match_operator expression that
         matches the else clause.  Instead we test the underlying
@@ -2582,7 +2580,7 @@ cleanup_subreg_operands (insn)
        recog_data.operand[i] = alter_subreg (recog_data.operand_loc[i]);
       else if (GET_CODE (recog_data.operand[i]) == PLUS
               || GET_CODE (recog_data.operand[i]) == MULT
        recog_data.operand[i] = alter_subreg (recog_data.operand_loc[i]);
       else if (GET_CODE (recog_data.operand[i]) == PLUS
               || GET_CODE (recog_data.operand[i]) == MULT
-              || GET_CODE (recog_data.operand[i]) == MEM)
+              || MEM_P (recog_data.operand[i]))
        recog_data.operand[i] = walk_alter_subreg (recog_data.operand_loc[i]);
     }
 
        recog_data.operand[i] = walk_alter_subreg (recog_data.operand_loc[i]);
     }
 
@@ -2592,7 +2590,7 @@ cleanup_subreg_operands (insn)
        *recog_data.dup_loc[i] = alter_subreg (recog_data.dup_loc[i]);
       else if (GET_CODE (*recog_data.dup_loc[i]) == PLUS
               || GET_CODE (*recog_data.dup_loc[i]) == MULT
        *recog_data.dup_loc[i] = alter_subreg (recog_data.dup_loc[i]);
       else if (GET_CODE (*recog_data.dup_loc[i]) == PLUS
               || GET_CODE (*recog_data.dup_loc[i]) == MULT
-              || GET_CODE (*recog_data.dup_loc[i]) == MEM)
+              || MEM_P (*recog_data.dup_loc[i]))
        *recog_data.dup_loc[i] = walk_alter_subreg (recog_data.dup_loc[i]);
     }
 }
        *recog_data.dup_loc[i] = walk_alter_subreg (recog_data.dup_loc[i]);
     }
 }
@@ -2601,16 +2599,32 @@ cleanup_subreg_operands (insn)
    based on the thing it is a subreg of.  */
 
 rtx
    based on the thing it is a subreg of.  */
 
 rtx
-alter_subreg (xp)
-     rtx *xp;
+alter_subreg (rtx *xp)
 {
   rtx x = *xp;
   rtx y = SUBREG_REG (x);
 
   /* simplify_subreg does not remove subreg from volatile references.
      We are required to.  */
 {
   rtx x = *xp;
   rtx y = SUBREG_REG (x);
 
   /* simplify_subreg does not remove subreg from volatile references.
      We are required to.  */
-  if (GET_CODE (y) == MEM)
-    *xp = adjust_address (y, GET_MODE (x), SUBREG_BYTE (x));
+  if (MEM_P (y))
+    {
+      int offset = SUBREG_BYTE (x);
+
+      /* For paradoxical subregs on big-endian machines, SUBREG_BYTE
+        contains 0 instead of the proper offset.  See simplify_subreg.  */
+      if (offset == 0
+         && GET_MODE_SIZE (GET_MODE (y)) < GET_MODE_SIZE (GET_MODE (x)))
+        {
+          int difference = GET_MODE_SIZE (GET_MODE (y))
+                          - GET_MODE_SIZE (GET_MODE (x));
+          if (WORDS_BIG_ENDIAN)
+            offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
+          if (BYTES_BIG_ENDIAN)
+            offset += difference % UNITS_PER_WORD;
+        }
+
+      *xp = adjust_address (y, GET_MODE (x), offset);
+    }
   else
     {
       rtx new = simplify_subreg (GET_MODE (x), y, GET_MODE (y),
   else
     {
       rtx new = simplify_subreg (GET_MODE (x), y, GET_MODE (y),
@@ -2618,14 +2632,13 @@ alter_subreg (xp)
 
       if (new != 0)
        *xp = new;
 
       if (new != 0)
        *xp = new;
-      /* Simplify_subreg can't handle some REG cases, but we have to.  */
-      else if (GET_CODE (y) == REG)
+      else
        {
        {
-         unsigned int regno = subreg_hard_regno (x, 1);
+         /* Simplify_subreg can't handle some REG cases, but we have to.  */
+         unsigned int regno = subreg_regno (x);
+         gcc_assert (REG_P (y));
          *xp = gen_rtx_REG_offset (y, GET_MODE (x), regno, SUBREG_BYTE (x));
        }
          *xp = gen_rtx_REG_offset (y, GET_MODE (x), regno, SUBREG_BYTE (x));
        }
-      else
-       abort ();
     }
 
   return *xp;
     }
 
   return *xp;
@@ -2634,19 +2647,20 @@ alter_subreg (xp)
 /* Do alter_subreg on all the SUBREGs contained in X.  */
 
 static rtx
 /* Do alter_subreg on all the SUBREGs contained in X.  */
 
 static rtx
-walk_alter_subreg (xp)
-     rtx *xp;
+walk_alter_subreg (rtx *xp)
 {
   rtx x = *xp;
   switch (GET_CODE (x))
     {
     case PLUS:
     case MULT:
 {
   rtx x = *xp;
   switch (GET_CODE (x))
     {
     case PLUS:
     case MULT:
+    case AND:
       XEXP (x, 0) = walk_alter_subreg (&XEXP (x, 0));
       XEXP (x, 1) = walk_alter_subreg (&XEXP (x, 1));
       break;
 
     case MEM:
       XEXP (x, 0) = walk_alter_subreg (&XEXP (x, 0));
       XEXP (x, 1) = walk_alter_subreg (&XEXP (x, 1));
       break;
 
     case MEM:
+    case ZERO_EXTEND:
       XEXP (x, 0) = walk_alter_subreg (&XEXP (x, 0));
       break;
 
       XEXP (x, 0) = walk_alter_subreg (&XEXP (x, 0));
       break;
 
@@ -2672,8 +2686,7 @@ walk_alter_subreg (xp)
    2 means that COND has been altered.  */
 
 static int
    2 means that COND has been altered.  */
 
 static int
-alter_cond (cond)
-     rtx cond;
+alter_cond (rtx cond)
 {
   int value = 0;
 
 {
   int value = 0;
 
@@ -2776,7 +2789,7 @@ alter_cond (cond)
     switch (GET_CODE (cond))
       {
       default:
     switch (GET_CODE (cond))
       {
       default:
-       abort ();
+       gcc_unreachable ();
 
       case NE:
        PUT_CODE (cond, cc_status.flags & CC_Z_IN_N ? GE : LT);
 
       case NE:
        PUT_CODE (cond, cc_status.flags & CC_Z_IN_N ? GE : LT);
@@ -2826,15 +2839,16 @@ alter_cond (cond)
    In an `asm', it's the user's fault; otherwise, the compiler's fault.  */
 
 void
    In an `asm', it's the user's fault; otherwise, the compiler's fault.  */
 
 void
-output_operand_lossage VPARAMS ((const char *msgid, ...))
+output_operand_lossage (const char *msgid, ...)
 {
   char *fmt_string;
   char *new_message;
   const char *pfx_str;
 {
   char *fmt_string;
   char *new_message;
   const char *pfx_str;
-  VA_OPEN (ap, msgid);
-  VA_FIXEDARG (ap, const char *, msgid);
+  va_list ap;
 
 
-  pfx_str = this_is_asm_operands ? _("invalid `asm': ") : "output_operand: ";
+  va_start (ap, msgid);
+
+  pfx_str = this_is_asm_operands ? _("invalid 'asm': ") : "output_operand: ";
   asprintf (&fmt_string, "%s%s", pfx_str, _(msgid));
   vasprintf (&new_message, fmt_string, ap);
 
   asprintf (&fmt_string, "%s%s", pfx_str, _(msgid));
   vasprintf (&new_message, fmt_string, ap);
 
@@ -2845,7 +2859,7 @@ output_operand_lossage VPARAMS ((const char *msgid, ...))
 
   free (fmt_string);
   free (new_message);
 
   free (fmt_string);
   free (new_message);
-  VA_CLOSE (ap);
+  va_end (ap);
 }
 \f
 /* Output of assembler code from a template, and its subroutines.  */
 }
 \f
 /* Output of assembler code from a template, and its subroutines.  */
@@ -2854,7 +2868,7 @@ output_operand_lossage VPARAMS ((const char *msgid, ...))
    alternative used.  */
 
 static void
    alternative used.  */
 
 static void
-output_asm_name ()
+output_asm_name (void)
 {
   if (debug_insn)
     {
 {
   if (debug_insn)
     {
@@ -2879,18 +2893,16 @@ output_asm_name ()
    corresponds to the address of the object and 0 if to the object.  */
 
 static tree
    corresponds to the address of the object and 0 if to the object.  */
 
 static tree
-get_mem_expr_from_op (op, paddressp)
-     rtx op;
-     int *paddressp;
+get_mem_expr_from_op (rtx op, int *paddressp)
 {
   tree expr;
   int inner_addressp;
 
   *paddressp = 0;
 
 {
   tree expr;
   int inner_addressp;
 
   *paddressp = 0;
 
-  if (GET_CODE (op) == REG)
+  if (REG_P (op))
     return REG_EXPR (op);
     return REG_EXPR (op);
-  else if (GET_CODE (op) != MEM)
+  else if (!MEM_P (op))
     return 0;
 
   if (MEM_EXPR (op) != 0)
     return 0;
 
   if (MEM_EXPR (op) != 0)
@@ -2909,8 +2921,8 @@ get_mem_expr_from_op (op, paddressp)
           && (expr = get_mem_expr_from_op (XEXP (op, 1), &inner_addressp)))
     return expr;
 
           && (expr = get_mem_expr_from_op (XEXP (op, 1), &inner_addressp)))
     return expr;
 
-  while (GET_RTX_CLASS (GET_CODE (op)) == '1'
-        || GET_RTX_CLASS (GET_CODE (op)) == '2')
+  while (GET_RTX_CLASS (GET_CODE (op)) == RTX_UNARY
+        || GET_RTX_CLASS (GET_CODE (op)) == RTX_BIN_ARITH)
     op = XEXP (op, 0);
 
   expr = get_mem_expr_from_op (op, &inner_addressp);
     op = XEXP (op, 0);
 
   expr = get_mem_expr_from_op (op, &inner_addressp);
@@ -2922,10 +2934,7 @@ get_mem_expr_from_op (op, paddressp)
    is the number of operands to write.  */
 
 static void
    is the number of operands to write.  */
 
 static void
-output_asm_operand_names (operands, oporder, nops)
-     rtx *operands;
-     int *oporder;
-     int nops;
+output_asm_operand_names (rtx *operands, int *oporder, int nops)
 {
   int wrote = 0;
   int i;
 {
   int wrote = 0;
   int i;
@@ -2969,9 +2978,7 @@ output_asm_operand_names (operands, oporder, nops)
       of the operand, with no other punctuation.  */
 
 void
       of the operand, with no other punctuation.  */
 
 void
-output_asm_insn (template, operands)
-     const char *template;
-     rtx *operands;
+output_asm_insn (const char *template, rtx *operands)
 {
   const char *p;
   int c;
 {
   const char *p;
   int c;
@@ -3094,61 +3101,66 @@ output_asm_insn (template, operands)
        else if (ISALPHA (*p))
          {
            int letter = *p++;
        else if (ISALPHA (*p))
          {
            int letter = *p++;
-           c = atoi (p);
-
-           if (! ISDIGIT (*p))
-             output_operand_lossage ("operand number missing after %%-letter");
-           else if (this_is_asm_operands
-                    && (c < 0 || (unsigned int) c >= insn_noperands))
+           unsigned long opnum;
+           char *endptr;
+           
+           opnum = strtoul (p, &endptr, 10);
+
+           if (endptr == p)
+             output_operand_lossage ("operand number missing "
+                                     "after %%-letter");
+           else if (this_is_asm_operands && opnum >= insn_noperands)
              output_operand_lossage ("operand number out of range");
            else if (letter == 'l')
              output_operand_lossage ("operand number out of range");
            else if (letter == 'l')
-             output_asm_label (operands[c]);
+             output_asm_label (operands[opnum]);
            else if (letter == 'a')
            else if (letter == 'a')
-             output_address (operands[c]);
+             output_address (operands[opnum]);
            else if (letter == 'c')
              {
            else if (letter == 'c')
              {
-               if (CONSTANT_ADDRESS_P (operands[c]))
-                 output_addr_const (asm_out_file, operands[c]);
+               if (CONSTANT_ADDRESS_P (operands[opnum]))
+                 output_addr_const (asm_out_file, operands[opnum]);
                else
                else
-                 output_operand (operands[c], 'c');
+                 output_operand (operands[opnum], 'c');
              }
            else if (letter == 'n')
              {
              }
            else if (letter == 'n')
              {
-               if (GET_CODE (operands[c]) == CONST_INT)
+               if (GET_CODE (operands[opnum]) == CONST_INT)
                  fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC,
                  fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC,
-                          - INTVAL (operands[c]));
+                          - INTVAL (operands[opnum]));
                else
                  {
                    putc ('-', asm_out_file);
                else
                  {
                    putc ('-', asm_out_file);
-                   output_addr_const (asm_out_file, operands[c]);
+                   output_addr_const (asm_out_file, operands[opnum]);
                  }
              }
            else
                  }
              }
            else
-             output_operand (operands[c], letter);
+             output_operand (operands[opnum], letter);
 
 
-           if (!opoutput[c])
-             oporder[ops++] = c;
-           opoutput[c] = 1;
+           if (!opoutput[opnum])
+             oporder[ops++] = opnum;
+           opoutput[opnum] = 1;
 
 
-           while (ISDIGIT (c = *p))
-             p++;
+           p = endptr;
+           c = *p;
          }
        /* % followed by a digit outputs an operand the default way.  */
        else if (ISDIGIT (*p))
          {
          }
        /* % followed by a digit outputs an operand the default way.  */
        else if (ISDIGIT (*p))
          {
-           c = atoi (p);
-           if (this_is_asm_operands
-               && (c < 0 || (unsigned int) c >= insn_noperands))
+           unsigned long opnum;
+           char *endptr;
+           
+           opnum = strtoul (p, &endptr, 10);
+           if (this_is_asm_operands && opnum >= insn_noperands)
              output_operand_lossage ("operand number out of range");
            else
              output_operand_lossage ("operand number out of range");
            else
-             output_operand (operands[c], 0);
+             output_operand (operands[opnum], 0);
 
 
-           if (!opoutput[c])
-             oporder[ops++] = c;
-           opoutput[c] = 1;
+           if (!opoutput[opnum])
+             oporder[ops++] = opnum;
+           opoutput[opnum] = 1;
 
 
-           while (ISDIGIT (c = *p))
-             p++;
+           p = endptr;
+           c = *p;
          }
        /* % followed by punctuation: output something for that
           punctuation character alone, with no operand.
          }
        /* % followed by punctuation: output something for that
           punctuation character alone, with no operand.
@@ -3177,19 +3189,18 @@ output_asm_insn (template, operands)
 /* Output a LABEL_REF, or a bare CODE_LABEL, as an assembler symbol.  */
 
 void
 /* Output a LABEL_REF, or a bare CODE_LABEL, as an assembler symbol.  */
 
 void
-output_asm_label (x)
-     rtx x;
+output_asm_label (rtx x)
 {
   char buf[256];
 
   if (GET_CODE (x) == LABEL_REF)
     x = XEXP (x, 0);
 {
   char buf[256];
 
   if (GET_CODE (x) == LABEL_REF)
     x = XEXP (x, 0);
-  if (GET_CODE (x) == CODE_LABEL
-      || (GET_CODE (x) == NOTE
+  if (LABEL_P (x)
+      || (NOTE_P (x)
          && NOTE_LINE_NUMBER (x) == NOTE_INSN_DELETED_LABEL))
     ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
   else
          && NOTE_LINE_NUMBER (x) == NOTE_INSN_DELETED_LABEL))
     ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
   else
-    output_operand_lossage ("`%%l' operand isn't a label");
+    output_operand_lossage ("'%%l' operand isn't a label");
 
   assemble_name (asm_out_file, buf);
 }
 
   assemble_name (asm_out_file, buf);
 }
@@ -3205,18 +3216,14 @@ output_asm_label (x)
    by PRINT_OPERAND.  */
 
 static void
    by PRINT_OPERAND.  */
 
 static void
-output_operand (x, code)
-     rtx x;
-     int code ATTRIBUTE_UNUSED;
+output_operand (rtx x, int code ATTRIBUTE_UNUSED)
 {
   if (x && GET_CODE (x) == SUBREG)
     x = alter_subreg (&x);
 
   /* If X is a pseudo-register, abort now rather than writing trash to the
      assembler file.  */
 {
   if (x && GET_CODE (x) == SUBREG)
     x = alter_subreg (&x);
 
   /* If X is a pseudo-register, abort now rather than writing trash to the
      assembler file.  */
-
-  if (x && GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
-    abort ();
+  gcc_assert (!x || !REG_P (x) || REGNO (x) < FIRST_PSEUDO_REGISTER);
 
   PRINT_OPERAND (asm_out_file, x, code);
 }
 
   PRINT_OPERAND (asm_out_file, x, code);
 }
@@ -3226,8 +3233,7 @@ output_operand (x, code)
    The macro PRINT_OPERAND_ADDRESS exists just to control this function.  */
 
 void
    The macro PRINT_OPERAND_ADDRESS exists just to control this function.  */
 
 void
-output_address (x)
-     rtx x;
+output_address (rtx x)
 {
   walk_alter_subreg (&x);
   PRINT_OPERAND_ADDRESS (asm_out_file, x);
 {
   walk_alter_subreg (&x);
   PRINT_OPERAND_ADDRESS (asm_out_file, x);
@@ -3238,9 +3244,7 @@ output_address (x)
    that may appear in these expressions.  */
 
 void
    that may appear in these expressions.  */
 
 void
-output_addr_const (file, x)
-     FILE *file;
-     rtx x;
+output_addr_const (FILE *file, rtx x)
 {
   char buf[256];
 
 {
   char buf[256];
 
@@ -3252,6 +3256,8 @@ output_addr_const (file, x)
       break;
 
     case SYMBOL_REF:
       break;
 
     case SYMBOL_REF:
+      if (SYMBOL_REF_DECL (x))
+       mark_decl_referenced (SYMBOL_REF_DECL (x));
 #ifdef ASM_OUTPUT_SYMBOL_REF
       ASM_OUTPUT_SYMBOL_REF (file, x);
 #else
 #ifdef ASM_OUTPUT_SYMBOL_REF
       ASM_OUTPUT_SYMBOL_REF (file, x);
 #else
@@ -3362,19 +3368,18 @@ output_addr_const (file, x)
    %U prints the value of USER_LABEL_PREFIX.
    %I prints the value of IMMEDIATE_PREFIX.
    %O runs ASM_OUTPUT_OPCODE to transform what follows in the string.
    %U prints the value of USER_LABEL_PREFIX.
    %I prints the value of IMMEDIATE_PREFIX.
    %O runs ASM_OUTPUT_OPCODE to transform what follows in the string.
-   Also supported are %d, %x, %s, %e, %f, %g and %%.
+   Also supported are %d, %i, %u, %x, %X, %o, %c, %s and %%.
 
    We handle alternate assembler dialects here, just like output_asm_insn.  */
 
 void
 
    We handle alternate assembler dialects here, just like output_asm_insn.  */
 
 void
-asm_fprintf VPARAMS ((FILE *file, const char *p, ...))
+asm_fprintf (FILE *file, const char *p, ...)
 {
   char buf[10];
   char *q, c;
 {
   char buf[10];
   char *q, c;
+  va_list argptr;
 
 
-  VA_OPEN (argptr, p);
-  VA_FIXEDARG (argptr, FILE *, file);
-  VA_FIXEDARG (argptr, const char *, p);
+  va_start (argptr, p);
 
   buf[0] = '%';
 
 
   buf[0] = '%';
 
@@ -3412,6 +3417,11 @@ asm_fprintf VPARAMS ((FILE *file, const char *p, ...))
       case '%':
        c = *p++;
        q = &buf[1];
       case '%':
        c = *p++;
        q = &buf[1];
+       while (strchr ("-+ #0", c))
+         {
+           *q++ = c;
+           c = *p++;
+         }
        while (ISDIGIT (c) || c == '.')
          {
            *q++ = c;
        while (ISDIGIT (c) || c == '.')
          {
            *q++ = c;
@@ -3420,32 +3430,24 @@ asm_fprintf VPARAMS ((FILE *file, const char *p, ...))
        switch (c)
          {
          case '%':
        switch (c)
          {
          case '%':
-           fprintf (file, "%%");
+           putc ('%', file);
            break;
 
          case 'd':  case 'i':  case 'u':
            break;
 
          case 'd':  case 'i':  case 'u':
-         case 'x':  case 'p':  case 'X':
-         case 'o':
+         case 'x':  case 'X':  case 'o':
+         case 'c':
            *q++ = c;
            *q = 0;
            fprintf (file, buf, va_arg (argptr, int));
            break;
 
          case 'w':
            *q++ = c;
            *q = 0;
            fprintf (file, buf, va_arg (argptr, int));
            break;
 
          case 'w':
-           /* This is a prefix to the 'd', 'i', 'u', 'x', 'p', and 'X' cases,
-              but we do not check for those cases.  It means that the value
-              is a HOST_WIDE_INT, which may be either `int' or `long'.  */
-
-#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
-#else
-#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
-           *q++ = 'l';
-#else
-           *q++ = 'l';
-           *q++ = 'l';
-#endif
-#endif
-
+           /* This is a prefix to the 'd', 'i', 'u', 'x', 'X', and
+              'o' cases, but we do not check for those cases.  It
+              means that the value is a HOST_WIDE_INT, which may be
+              either `long' or `long long'.  */
+           memcpy (q, HOST_WIDE_INT_PRINT, strlen (HOST_WIDE_INT_PRINT));
+           q += strlen (HOST_WIDE_INT_PRINT);
            *q++ = *p++;
            *q = 0;
            fprintf (file, buf, va_arg (argptr, HOST_WIDE_INT));
            *q++ = *p++;
            *q = 0;
            fprintf (file, buf, va_arg (argptr, HOST_WIDE_INT));
@@ -3453,17 +3455,22 @@ asm_fprintf VPARAMS ((FILE *file, const char *p, ...))
 
          case 'l':
            *q++ = c;
 
          case 'l':
            *q++ = c;
-           *q++ = *p++;
-           *q = 0;
-           fprintf (file, buf, va_arg (argptr, long));
-           break;
+#ifdef HAVE_LONG_LONG
+           if (*p == 'l')
+             {
+               *q++ = *p++;
+               *q++ = *p++;
+               *q = 0;
+               fprintf (file, buf, va_arg (argptr, long long));
+             }
+           else
+#endif
+             {
+               *q++ = *p++;
+               *q = 0;
+               fprintf (file, buf, va_arg (argptr, long));
+             }
 
 
-         case 'e':
-         case 'f':
-         case 'g':
-           *q++ = c;
-           *q = 0;
-           fprintf (file, buf, va_arg (argptr, double));
            break;
 
          case 's':
            break;
 
          case 's':
@@ -3501,7 +3508,7 @@ asm_fprintf VPARAMS ((FILE *file, const char *p, ...))
            break;
 
 #ifdef ASM_FPRINTF_EXTENSIONS
            break;
 
 #ifdef ASM_FPRINTF_EXTENSIONS
-           /* Upper case letters are reserved for general use by asm_fprintf
+           /* Uppercase letters are reserved for general use by asm_fprintf
               and so are not available to target specific code.  In order to
               prevent the ASM_FPRINTF_EXTENSIONS macro from using them then,
               they are defined here.  As they get turned into real extensions
               and so are not available to target specific code.  In order to
               prevent the ASM_FPRINTF_EXTENSIONS macro from using them then,
               they are defined here.  As they get turned into real extensions
@@ -3515,14 +3522,14 @@ asm_fprintf VPARAMS ((FILE *file, const char *p, ...))
          ASM_FPRINTF_EXTENSIONS (file, argptr, p)
 #endif
          default:
          ASM_FPRINTF_EXTENSIONS (file, argptr, p)
 #endif
          default:
-           abort ();
+           gcc_unreachable ();
          }
        break;
 
       default:
          }
        break;
 
       default:
-       fputc (c, file);
+       putc (c, file);
       }
       }
-  VA_CLOSE (argptr);
+  va_end (argptr);
 }
 \f
 /* Split up a CONST_DOUBLE or integer constant rtx
 }
 \f
 /* Split up a CONST_DOUBLE or integer constant rtx
@@ -3531,9 +3538,7 @@ asm_fprintf VPARAMS ((FILE *file, const char *p, ...))
    and in *SECOND the other.  */
 
 void
    and in *SECOND the other.  */
 
 void
-split_double (value, first, second)
-     rtx value;
-     rtx *first, *second;
+split_double (rtx value, rtx *first, rtx *second)
 {
   if (GET_CODE (value) == CONST_INT)
     {
 {
   if (GET_CODE (value) == CONST_INT)
     {
@@ -3664,15 +3669,15 @@ split_double (value, first, second)
        }
 #endif
 
        }
 #endif
 
-      *first = GEN_INT ((HOST_WIDE_INT) l[0]);
-      *second = GEN_INT ((HOST_WIDE_INT) l[1]);
+      *first = GEN_INT (l[0]);
+      *second = GEN_INT (l[1]);
     }
 }
 \f
 /* Return nonzero if this function has no function calls.  */
 
 int
     }
 }
 \f
 /* Return nonzero if this function has no function calls.  */
 
 int
-leaf_function_p ()
+leaf_function_p (void)
 {
   rtx insn;
   rtx link;
 {
   rtx insn;
   rtx link;
@@ -3682,12 +3687,12 @@ leaf_function_p ()
 
   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
     {
 
   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
     {
-      if (GET_CODE (insn) == CALL_INSN
+      if (CALL_P (insn)
          && ! SIBLING_CALL_P (insn))
        return 0;
          && ! SIBLING_CALL_P (insn))
        return 0;
-      if (GET_CODE (insn) == INSN
+      if (NONJUMP_INSN_P (insn)
          && GET_CODE (PATTERN (insn)) == SEQUENCE
          && GET_CODE (PATTERN (insn)) == SEQUENCE
-         && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == CALL_INSN
+         && CALL_P (XVECEXP (PATTERN (insn), 0, 0))
          && ! SIBLING_CALL_P (XVECEXP (PATTERN (insn), 0, 0)))
        return 0;
     }
          && ! SIBLING_CALL_P (XVECEXP (PATTERN (insn), 0, 0)))
        return 0;
     }
@@ -3697,12 +3702,12 @@ leaf_function_p ()
     {
       insn = XEXP (link, 0);
 
     {
       insn = XEXP (link, 0);
 
-      if (GET_CODE (insn) == CALL_INSN
+      if (CALL_P (insn)
          && ! SIBLING_CALL_P (insn))
        return 0;
          && ! SIBLING_CALL_P (insn))
        return 0;
-      if (GET_CODE (insn) == INSN
+      if (NONJUMP_INSN_P (insn)
          && GET_CODE (PATTERN (insn)) == SEQUENCE
          && GET_CODE (PATTERN (insn)) == SEQUENCE
-         && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == CALL_INSN
+         && CALL_P (XVECEXP (PATTERN (insn), 0, 0))
          && ! SIBLING_CALL_P (XVECEXP (PATTERN (insn), 0, 0)))
        return 0;
     }
          && ! SIBLING_CALL_P (XVECEXP (PATTERN (insn), 0, 0)))
        return 0;
     }
@@ -3715,17 +3720,15 @@ leaf_function_p ()
    output templates to customary add branch prediction hints.
  */
 int
    output templates to customary add branch prediction hints.
  */
 int
-final_forward_branch_p (insn)
-     rtx insn;
+final_forward_branch_p (rtx insn)
 {
   int insn_id, label_id;
 {
   int insn_id, label_id;
-  if (!uid_shuid)
-    abort ();
+  
+  gcc_assert (uid_shuid);
   insn_id = INSN_SHUID (insn);
   label_id = INSN_SHUID (JUMP_LABEL (insn));
   /* We've hit some insns that does not have id information available.  */
   insn_id = INSN_SHUID (insn);
   label_id = INSN_SHUID (JUMP_LABEL (insn));
   /* We've hit some insns that does not have id information available.  */
-  if (!insn_id || !label_id)
-    abort ();
+  gcc_assert (insn_id && label_id);
   return insn_id < label_id;
 }
 
   return insn_id < label_id;
 }
 
@@ -3744,7 +3747,7 @@ final_forward_branch_p (insn)
    safely renumbered.  */
 
 int
    safely renumbered.  */
 
 int
-only_leaf_regs_used ()
+only_leaf_regs_used (void)
 {
   int i;
   const char *const permitted_reg_in_leaf_functions = LEAF_REGISTERS;
 {
   int i;
   const char *const permitted_reg_in_leaf_functions = LEAF_REGISTERS;
@@ -3756,7 +3759,7 @@ only_leaf_regs_used ()
 
   if (current_function_uses_pic_offset_table
       && pic_offset_table_rtx != 0
 
   if (current_function_uses_pic_offset_table
       && pic_offset_table_rtx != 0
-      && GET_CODE (pic_offset_table_rtx) == REG
+      && REG_P (pic_offset_table_rtx)
       && ! permitted_reg_in_leaf_functions[REGNO (pic_offset_table_rtx)])
     return 0;
 
       && ! permitted_reg_in_leaf_functions[REGNO (pic_offset_table_rtx)])
     return 0;
 
@@ -3767,8 +3770,7 @@ only_leaf_regs_used ()
    available in leaf functions.  */
 
 static void
    available in leaf functions.  */
 
 static void
-leaf_renumber_regs (first)
-     rtx first;
+leaf_renumber_regs (rtx first)
 {
   rtx insn;
 
 {
   rtx insn;
 
@@ -3789,8 +3791,7 @@ leaf_renumber_regs (first)
    available in leaf functions.  */
 
 void
    available in leaf functions.  */
 
 void
-leaf_renumber_regs_insn (in_rtx)
-     rtx in_rtx;
+leaf_renumber_regs_insn (rtx in_rtx)
 {
   int i, j;
   const char *format_ptr;
 {
   int i, j;
   const char *format_ptr;
@@ -3802,7 +3803,7 @@ leaf_renumber_regs_insn (in_rtx)
      renumbered_regs would be 1 for an output-register;
      they  */
 
      renumbered_regs would be 1 for an output-register;
      they  */
 
-  if (GET_CODE (in_rtx) == REG)
+  if (REG_P (in_rtx))
     {
       int newreg;
 
     {
       int newreg;
 
@@ -3819,8 +3820,7 @@ leaf_renumber_regs_insn (in_rtx)
          return;
        }
       newreg = LEAF_REG_REMAP (newreg);
          return;
        }
       newreg = LEAF_REG_REMAP (newreg);
-      if (newreg < 0)
-       abort ();
+      gcc_assert (newreg >= 0);
       regs_ever_live[REGNO (in_rtx)] = 0;
       regs_ever_live[newreg] = 1;
       REGNO (in_rtx) = newreg;
       regs_ever_live[REGNO (in_rtx)] = 0;
       regs_ever_live[newreg] = 1;
       REGNO (in_rtx) = newreg;
@@ -3863,7 +3863,89 @@ leaf_renumber_regs_insn (in_rtx)
        break;
 
       default:
        break;
 
       default:
-       abort ();
+       gcc_unreachable ();
       }
 }
 #endif
       }
 }
 #endif
+
+
+/* When -gused is used, emit debug info for only used symbols. But in
+   addition to the standard intercepted debug_hooks there are some direct
+   calls into this file, i.e., dbxout_symbol, dbxout_parms, and dbxout_reg_params.
+   Those routines may also be called from a higher level intercepted routine. So
+   to prevent recording data for an inner call to one of these for an intercept,
+   we maintain an intercept nesting counter (debug_nesting). We only save the
+   intercepted arguments if the nesting is 1.  */
+int debug_nesting = 0;
+
+static tree *symbol_queue;
+int symbol_queue_index = 0;
+static int symbol_queue_size = 0;
+
+/* Generate the symbols for any queued up type symbols we encountered
+   while generating the type info for some originally used symbol.
+   This might generate additional entries in the queue.  Only when
+   the nesting depth goes to 0 is this routine called.  */
+
+void
+debug_flush_symbol_queue (void)
+{
+  int i;
+
+  /* Make sure that additionally queued items are not flushed
+     prematurely.  */
+
+  ++debug_nesting;
+
+  for (i = 0; i < symbol_queue_index; ++i)
+    {
+      /* If we pushed queued symbols then such symbols are must be
+         output no matter what anyone else says.  Specifically,
+         we need to make sure dbxout_symbol() thinks the symbol was
+         used and also we need to override TYPE_DECL_SUPPRESS_DEBUG
+         which may be set for outside reasons.  */
+      int saved_tree_used = TREE_USED (symbol_queue[i]);
+      int saved_suppress_debug = TYPE_DECL_SUPPRESS_DEBUG (symbol_queue[i]);
+      TREE_USED (symbol_queue[i]) = 1;
+      TYPE_DECL_SUPPRESS_DEBUG (symbol_queue[i]) = 0;
+
+#ifdef DBX_DEBUGGING_INFO
+      dbxout_symbol (symbol_queue[i], 0);
+#endif
+
+      TREE_USED (symbol_queue[i]) = saved_tree_used;
+      TYPE_DECL_SUPPRESS_DEBUG (symbol_queue[i]) = saved_suppress_debug;
+    }
+
+  symbol_queue_index = 0;
+  --debug_nesting;
+}
+
+/* Queue a type symbol needed as part of the definition of a decl
+   symbol.  These symbols are generated when debug_flush_symbol_queue()
+   is called.  */
+
+void
+debug_queue_symbol (tree decl)
+{
+  if (symbol_queue_index >= symbol_queue_size)
+    {
+      symbol_queue_size += 10;
+      symbol_queue = xrealloc (symbol_queue,
+                              symbol_queue_size * sizeof (tree));
+    }
+
+  symbol_queue[symbol_queue_index++] = decl;
+}
+
+/* Free symbol queue.  */
+void
+debug_free_queue (void)
+{
+  if (symbol_queue)
+    {
+      free (symbol_queue);
+      symbol_queue = NULL;
+      symbol_queue_size = 0;
+    }
+}