OSDN Git Service

2008-05-09 H.J. Lu <hongjiu.lu@intel.com>
[pf3gnuchains/gcc-fork.git] / gcc / final.c
index ef1eeb2..b318581 100644 (file)
@@ -1,12 +1,13 @@
 /* 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, 2003, 2004 Free Software Foundation, Inc.
+   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+   Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -15,9 +16,8 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 /* This is the final pass of the compiler.
    It looks at the rtl code for a function and outputs assembler code.
 
 /* This is the final pass of the compiler.
    It looks at the rtl code for a function and outputs assembler code.
@@ -71,6 +71,15 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "debug.h"
 #include "expr.h"
 #include "cfglayout.h"
 #include "debug.h"
 #include "expr.h"
 #include "cfglayout.h"
+#include "tree-pass.h"
+#include "timevar.h"
+#include "cgraph.h"
+#include "coverage.h"
+#include "df.h"
+#include "vecprim.h"
+#include "ggc.h"
+#include "cfgloop.h"
+#include "params.h"
 
 #ifdef XCOFF_DEBUGGING_INFO
 #include "xcoffout.h"          /* Needed for external data
 
 #ifdef XCOFF_DEBUGGING_INFO
 #include "xcoffout.h"          /* Needed for external data
@@ -85,6 +94,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "dbxout.h"
 #endif
 
 #include "dbxout.h"
 #endif
 
+#ifdef SDB_DEBUGGING_INFO
+#include "sdbout.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
@@ -98,19 +111,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 /* Is the given character a logical line separator for the assembler?  */
 #ifndef IS_ASM_LOGICAL_LINE_SEPARATOR
 
 /* Is the given character a logical line separator for the assembler?  */
 #ifndef IS_ASM_LOGICAL_LINE_SEPARATOR
-#define IS_ASM_LOGICAL_LINE_SEPARATOR(C) ((C) == ';')
+#define IS_ASM_LOGICAL_LINE_SEPARATOR(C, STR) ((C) == ';')
 #endif
 
 #ifndef JUMP_TABLES_IN_TEXT_SECTION
 #define JUMP_TABLES_IN_TEXT_SECTION 0
 #endif
 
 #endif
 
 #ifndef JUMP_TABLES_IN_TEXT_SECTION
 #define JUMP_TABLES_IN_TEXT_SECTION 0
 #endif
 
-#if defined(READONLY_DATA_SECTION) || defined(READONLY_DATA_SECTION_ASM_OP)
-#define HAVE_READONLY_DATA_SECTION 1
-#else
-#define HAVE_READONLY_DATA_SECTION 0
-#endif
-
 /* Bitflags used by final_scan_insn.  */
 #define SEEN_BB                1
 #define SEEN_NOTE      2
 /* Bitflags used by final_scan_insn.  */
 #define SEEN_BB                1
 #define SEEN_NOTE      2
@@ -132,10 +139,17 @@ static int high_function_linenum;
 /* Filename of last NOTE.  */
 static const char *last_filename;
 
 /* Filename of last NOTE.  */
 static const char *last_filename;
 
-extern int length_unit_log; /* This is defined in insn-attrtab.c.  */
+/* Override filename and line number.  */
+static const char *override_filename;
+static int override_linenum;
+
+/* Whether to force emission of a line note before the next insn.  */
+static bool force_source_line = false;
+
+extern const int length_unit_log; /* This is defined in insn-attrtab.c.  */
 
 /* Nonzero while outputting an `asm' with operands.
 
 /* Nonzero while outputting an `asm' with operands.
-   This means that inconsistencies are the user's fault, so don't abort.
+   This means that inconsistencies are the user's fault, so don't die.
    The precise value is the insn being output, to pass to error_for_asm.  */
 rtx this_is_asm_operands;
 
    The precise value is the insn being output, to pass to error_for_asm.  */
 rtx this_is_asm_operands;
 
@@ -164,23 +178,6 @@ CC_STATUS cc_status;
 CC_STATUS cc_prev_status;
 #endif
 
 CC_STATUS cc_prev_status;
 #endif
 
-/* Indexed by hardware reg number, is 1 if that register is ever
-   used in the current function.
-
-   In life_analysis, or in stupid_life_analysis, this is set
-   up to record the hard regs used explicitly.  Reload adds
-   in the hard regs used for holding pseudo regs.  Final uses
-   it to generate the code in the function prologue and epilogue
-   to save and restore registers as needed.  */
-
-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.
    Initialized in function.c to 0.  Set only in reload1.c as per
    the needs of the function.  */
 /* Nonzero means current function must be given a frame pointer.
    Initialized in function.c to 0.  Set only in reload1.c as per
    the needs of the function.  */
@@ -217,7 +214,7 @@ static int asm_insn_count (rtx);
 static void profile_function (FILE *);
 static void profile_after_prologue (FILE *);
 static bool notice_source_line (rtx);
 static void profile_function (FILE *);
 static void profile_after_prologue (FILE *);
 static bool notice_source_line (rtx);
-static rtx walk_alter_subreg (rtx *);
+static rtx walk_alter_subreg (rtx *, bool *);
 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_name (void);
 static void output_alternate_entry_point (FILE *, rtx);
 static tree get_mem_expr_from_op (rtx, int *);
@@ -314,7 +311,7 @@ dbr_sequence_length (void)
 
 static int *insn_lengths;
 
 
 static int *insn_lengths;
 
-varray_type insn_addresses_;
+VEC(int,heap) *insn_addresses_;
 
 /* Max uid for which the above arrays are valid.  */
 static int insn_lengths_max_uid;
 
 /* Max uid for which the above arrays are valid.  */
 static int insn_lengths_max_uid;
@@ -374,10 +371,11 @@ init_insn_lengths (void)
 }
 
 /* Obtain the current length of an insn.  If branch shortening has been done,
 }
 
 /* Obtain the current length of an insn.  If branch shortening has been done,
-   get its actual length.  Otherwise, get its maximum length.  */
-
-int
-get_attr_length (rtx insn ATTRIBUTE_UNUSED)
+   get its actual length.  Otherwise, use FALLBACK_FN to calculate the
+   length.  */
+static inline int
+get_attr_length_1 (rtx insn ATTRIBUTE_UNUSED,
+                  int (*fallback_fn) (rtx) ATTRIBUTE_UNUSED)
 {
 #ifdef HAVE_ATTR_length
   rtx body;
 {
 #ifdef HAVE_ATTR_length
   rtx body;
@@ -395,7 +393,7 @@ get_attr_length (rtx insn ATTRIBUTE_UNUSED)
        return 0;
 
       case CALL_INSN:
        return 0;
 
       case CALL_INSN:
-       length = insn_default_length (insn);
+       length = fallback_fn (insn);
        break;
 
       case JUMP_INSN:
        break;
 
       case JUMP_INSN:
@@ -406,7 +404,7 @@ get_attr_length (rtx insn ATTRIBUTE_UNUSED)
               ADDR_VEC_ALIGN.  */
          }
        else
               ADDR_VEC_ALIGN.  */
          }
        else
-         length = insn_default_length (insn);
+         length = fallback_fn (insn);
        break;
 
       case INSN:
        break;
 
       case INSN:
@@ -415,12 +413,12 @@ get_attr_length (rtx insn ATTRIBUTE_UNUSED)
          return 0;
 
        else if (GET_CODE (body) == ASM_INPUT || asm_noperands (body) >= 0)
          return 0;
 
        else if (GET_CODE (body) == ASM_INPUT || asm_noperands (body) >= 0)
-         length = asm_insn_count (body) * insn_default_length (insn);
+         length = asm_insn_count (body) * fallback_fn (insn);
        else if (GET_CODE (body) == SEQUENCE)
          for (i = 0; i < XVECLEN (body, 0); i++)
            length += get_attr_length (XVECEXP (body, 0, i));
        else
        else if (GET_CODE (body) == SEQUENCE)
          for (i = 0; i < XVECLEN (body, 0); i++)
            length += get_attr_length (XVECEXP (body, 0, i));
        else
-         length = insn_default_length (insn);
+         length = fallback_fn (insn);
        break;
 
       default:
        break;
 
       default:
@@ -433,8 +431,26 @@ get_attr_length (rtx insn ATTRIBUTE_UNUSED)
   return length;
 #else /* not HAVE_ATTR_length */
   return 0;
   return length;
 #else /* not HAVE_ATTR_length */
   return 0;
+#define insn_default_length 0
+#define insn_min_length 0
 #endif /* not HAVE_ATTR_length */
 }
 #endif /* not HAVE_ATTR_length */
 }
+
+/* Obtain the current length of an insn.  If branch shortening has been done,
+   get its actual length.  Otherwise, get its maximum length.  */
+int
+get_attr_length (rtx insn)
+{
+  return get_attr_length_1 (insn, insn_default_length);
+}
+
+/* Obtain the current length of an insn.  If branch shortening has been done,
+   get its actual length.  Otherwise, get its minimum length.  */
+int
+get_attr_min_length (rtx insn)
+{
+  return get_attr_length_1 (insn, insn_min_length);
+}
 \f
 /* Code to handle alignment inside shorten_branches.  */
 
 \f
 /* Code to handle alignment inside shorten_branches.  */
 
@@ -625,7 +641,7 @@ insn_current_reference_address (rtx 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,11 +667,16 @@ insn_current_reference_address (rtx branch)
 }
 #endif /* HAVE_ATTR_length */
 \f
 }
 #endif /* HAVE_ATTR_length */
 \f
-void
+/* Compute branch alignments based on frequency information in the
+   CFG.  */
+
+static unsigned int
 compute_alignments (void)
 {
   int log, max_skip, max_log;
   basic_block bb;
 compute_alignments (void)
 {
   int log, max_skip, max_log;
   basic_block bb;
+  int freq_max = 0;
+  int freq_threshold = 0;
 
   if (label_align)
     {
 
   if (label_align)
     {
@@ -665,32 +686,62 @@ compute_alignments (void)
 
   max_labelno = max_label_num ();
   min_labelno = get_first_label_num ();
 
   max_labelno = max_label_num ();
   min_labelno = get_first_label_num ();
-  label_align = xcalloc (max_labelno - min_labelno + 1,
-                        sizeof (struct label_alignment));
+  label_align = XCNEWVEC (struct label_alignment, max_labelno - min_labelno + 1);
 
   /* 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)
-    return;
+    return 0;
+
+  if (dump_file)
+    {
+      dump_flow_info (dump_file, TDF_DETAILS);
+      flow_loops_dump (dump_file, NULL, 1);
+      loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
+    }
+  FOR_EACH_BB (bb)
+    if (bb->frequency > freq_max)
+      freq_max = bb->frequency;
+  freq_threshold = freq_max / PARAM_VALUE (PARAM_ALIGN_THRESHOLD);
 
 
+  if (dump_file)
+    fprintf(dump_file, "freq_max: %i\n",freq_max);
   FOR_EACH_BB (bb)
     {
       rtx label = BB_HEAD (bb);
       int fallthru_frequency = 0, branch_frequency = 0, has_fallthru = 0;
       edge e;
   FOR_EACH_BB (bb)
     {
       rtx label = BB_HEAD (bb);
       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))
          || probably_never_executed_bb_p (bb))
-       continue;
+       {
+         if (dump_file)
+           fprintf(dump_file, "BB %4i freq %4i loop %2i loop_depth %2i skipped.\n",
+                   bb->index, bb->frequency, bb->loop_father->num, bb->loop_depth);
+         continue;
+       }
       max_log = LABEL_ALIGN (label);
       max_skip = LABEL_ALIGN_MAX_SKIP;
 
       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);
          else
            branch_frequency += EDGE_FREQUENCY (e);
        }
        {
          if (e->flags & EDGE_FALLTHRU)
            has_fallthru = 1, fallthru_frequency += EDGE_FREQUENCY (e);
          else
            branch_frequency += EDGE_FREQUENCY (e);
        }
+      if (dump_file)
+       {
+         fprintf(dump_file, "BB %4i freq %4i loop %2i loop_depth %2i fall %4i branch %4i",
+                 bb->index, bb->frequency, bb->loop_father->num,
+                 bb->loop_depth,
+                 fallthru_frequency, branch_frequency);
+         if (!bb->loop_father->inner && bb->loop_father->num)
+           fprintf (dump_file, " inner_loop");
+         if (bb->loop_father->header == bb)
+           fprintf (dump_file, " loop_header");
+         fprintf (dump_file, "\n");
+       }
 
       /* There are two purposes to align block with no fallthru incoming edge:
         1) to avoid fetch stalls when branch destination is near cache boundary
 
       /* There are two purposes to align block with no fallthru incoming edge:
         1) to avoid fetch stalls when branch destination is near cache boundary
@@ -703,12 +754,14 @@ compute_alignments (void)
         when function is called.  */
 
       if (!has_fallthru
         when function is called.  */
 
       if (!has_fallthru
-         && (branch_frequency > BB_FREQ_MAX / 10
+         && (branch_frequency > freq_threshold
              || (bb->frequency > bb->prev_bb->frequency * 10
                  && (bb->prev_bb->frequency
                      <= ENTRY_BLOCK_PTR->frequency / 2))))
        {
          log = JUMP_ALIGN (label);
              || (bb->frequency > bb->prev_bb->frequency * 10
                  && (bb->prev_bb->frequency
                      <= ENTRY_BLOCK_PTR->frequency / 2))))
        {
          log = JUMP_ALIGN (label);
+         if (dump_file)
+           fprintf(dump_file, "  jump alignment added.\n");
          if (max_log < log)
            {
              max_log = log;
          if (max_log < log)
            {
              max_log = log;
@@ -719,10 +772,13 @@ compute_alignments (void)
         align it.  It is most likely a first block of loop.  */
       if (has_fallthru
          && maybe_hot_bb_p (bb)
         align it.  It is most likely a first block of loop.  */
       if (has_fallthru
          && maybe_hot_bb_p (bb)
-         && branch_frequency + fallthru_frequency > BB_FREQ_MAX / 10
-         && branch_frequency > fallthru_frequency * 2)
+         && branch_frequency + fallthru_frequency > freq_threshold
+         && (branch_frequency
+             > fallthru_frequency * PARAM_VALUE (PARAM_ALIGN_LOOP_ITERATIONS)))
        {
          log = LOOP_ALIGN (label);
        {
          log = LOOP_ALIGN (label);
+         if (dump_file)
+           fprintf(dump_file, "  internal loop alignment added.\n");
          if (max_log < log)
            {
              max_log = log;
          if (max_log < log)
            {
              max_log = log;
@@ -732,7 +788,32 @@ compute_alignments (void)
       LABEL_TO_ALIGNMENT (label) = max_log;
       LABEL_TO_MAX_SKIP (label) = max_skip;
     }
       LABEL_TO_ALIGNMENT (label) = max_log;
       LABEL_TO_MAX_SKIP (label) = max_skip;
     }
+
+  if (dump_file)
+    loop_optimizer_finalize ();
+  return 0;
 }
 }
+
+struct rtl_opt_pass pass_compute_alignments =
+{
+ {
+  RTL_PASS,
+  "alignments",                         /* name */
+  NULL,                                 /* gate */
+  compute_alignments,                   /* execute */
+  NULL,                                 /* sub */
+  NULL,                                 /* next */
+  0,                                    /* static_pass_number */
+  0,                                    /* tv_id */
+  0,                                    /* properties_required */
+  0,                                    /* properties_provided */
+  0,                                    /* properties_destroyed */
+  0,                                    /* todo_flags_start */
+  TODO_dump_func | TODO_verify_rtl_sharing
+  | TODO_ggc_collect                    /* todo_flags_finish */
+ }
+};
+
 \f
 /* Make a pass over all insns and compute their actual lengths by shortening
    any branches of variable length if possible.  */
 \f
 /* Make a pass over all insns and compute their actual lengths by shortening
    any branches of variable length if possible.  */
@@ -767,10 +848,10 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
   /* 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 ();
 
-  /* Free uid_shuid before reallocating it.   */
+  /* Free uid_shuid before reallocating it.  */
   free (uid_shuid);
   free (uid_shuid);
-  
-  uid_shuid = xmalloc (max_uid * sizeof *uid_shuid);
+
+  uid_shuid = XNEWVEC (int, max_uid);
 
   if (max_labelno != max_label_num ())
     {
 
   if (max_labelno != max_label_num ())
     {
@@ -786,10 +867,9 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
       label_align = 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
+      /* Range of labels grows monotonically in the function.  Failing here
          means that the initialization of array got lost.  */
          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));
@@ -810,14 +890,9 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
 
       INSN_SHUID (insn) = i++;
       if (INSN_P (insn))
 
       INSN_SHUID (insn) = i++;
       if (INSN_P (insn))
-       {
-         /* reorg might make the first insn of a loop being run once only,
-             and delete the label in front of it.  Then we want to apply
-             the loop alignment to the new label created by reorg, which
-             is separated by the former loop start insn from the
-            NOTE_INSN_LOOP_BEG.  */
-       }
-      else if (GET_CODE (insn) == CODE_LABEL)
+       continue;
+
+      if (LABEL_P (insn))
        {
          rtx next;
 
        {
          rtx next;
 
@@ -835,11 +910,12 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
              max_log = log;
              max_skip = LABEL_ALIGN_MAX_SKIP;
            }
              max_log = log;
              max_skip = LABEL_ALIGN_MAX_SKIP;
            }
-         next = NEXT_INSN (insn);
+         next = next_nonnote_insn (insn);
          /* ADDR_VECs only take room if read-only data goes into the text
             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 (JUMP_TABLES_IN_TEXT_SECTION
+             || readonly_data_section == text_section)
+           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
@@ -858,13 +934,13 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
          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)
@@ -879,20 +955,20 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
 #ifdef HAVE_ATTR_length
 
   /* Allocate the rest of the arrays.  */
 #ifdef HAVE_ATTR_length
 
   /* Allocate the rest of the arrays.  */
-  insn_lengths = xmalloc (max_uid * sizeof (*insn_lengths));
+  insn_lengths = XNEWVEC (int, 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);
 
   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 = xcalloc (max_uid, sizeof (char));
+  varying_length = XCNEWVEC (char, max_uid);
 
   /* 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 = xcalloc (max_uid, sizeof *uid_align);
+  uid_align = XCNEWVEC (rtx, max_uid);
 
   for (i = MAX_CODE_ALIGN; --i >= 0;)
     align_tab[i] = NULL_RTX;
 
   for (i = MAX_CODE_ALIGN; --i >= 0;)
     align_tab[i] = NULL_RTX;
@@ -901,7 +977,7 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
     {
       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)
        {
@@ -928,13 +1004,12 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
          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--)
            {
@@ -953,10 +1028,11 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
              if (min_align > LABEL_TO_ALIGNMENT (lab))
                min_align = LABEL_TO_ALIGNMENT (lab);
            }
              if (min_align > LABEL_TO_ALIGNMENT (lab))
                min_align = LABEL_TO_ALIGNMENT (lab);
            }
-         XEXP (pat, 2) = gen_rtx_LABEL_REF (VOIDmode, min_lab);
-         XEXP (pat, 3) = gen_rtx_LABEL_REF (VOIDmode, max_lab);
+         XEXP (pat, 2) = gen_rtx_LABEL_REF (Pmode, min_lab);
+         XEXP (pat, 3) = gen_rtx_LABEL_REF (Pmode, max_lab);
          insn_shuid = INSN_SHUID (insn);
          rel = INSN_SHUID (XEXP (XEXP (pat, 0), 0));
          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;
@@ -977,7 +1053,7 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
 
       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)
@@ -990,8 +1066,8 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
 
       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;
@@ -1001,7 +1077,8 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
        {
          /* This only takes room if read-only data goes into the text
             section.  */
        {
          /* This only takes room if read-only data goes into the text
             section.  */
-         if (JUMP_TABLES_IN_TEXT_SECTION || !HAVE_READONLY_DATA_SECTION)
+         if (JUMP_TABLES_IN_TEXT_SECTION
+             || readonly_data_section == text_section)
            insn_lengths[uid] = (XVECLEN (body,
                                          GET_CODE (body) == ADDR_DIFF_VEC)
                                 * GET_MODE_SIZE (GET_MODE (body)));
            insn_lengths[uid] = (XVECLEN (body,
                                          GET_CODE (body) == ADDR_DIFF_VEC)
                                 * GET_MODE_SIZE (GET_MODE (body)));
@@ -1082,7 +1159,7 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
 
          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)
@@ -1107,7 +1184,7 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
          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);
@@ -1202,7 +1279,8 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
              PUT_MODE (body, CASE_VECTOR_SHORTEN_MODE (min_addr - rel_addr,
                                                        max_addr - rel_addr,
                                                        body));
              PUT_MODE (body, CASE_VECTOR_SHORTEN_MODE (min_addr - rel_addr,
                                                        max_addr - rel_addr,
                                                        body));
-             if (JUMP_TABLES_IN_TEXT_SECTION || !HAVE_READONLY_DATA_SECTION)
+             if (JUMP_TABLES_IN_TEXT_SECTION
+                 || readonly_data_section == text_section)
                {
                  insn_lengths[uid]
                    = (XVECLEN (body, 1) * GET_MODE_SIZE (GET_MODE (body)));
                {
                  insn_lengths[uid]
                    = (XVECLEN (body, 1) * GET_MODE_SIZE (GET_MODE (body)));
@@ -1217,7 +1295,7 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
 
          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;
@@ -1239,7 +1317,7 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED)
              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;
 
@@ -1312,16 +1390,83 @@ asm_insn_count (rtx body)
   if (GET_CODE (body) == ASM_INPUT)
     template = XSTR (body, 0);
   else
   if (GET_CODE (body) == ASM_INPUT)
     template = XSTR (body, 0);
   else
-    template = decode_asm_operands (body, NULL, NULL, NULL, NULL);
+    template = decode_asm_operands (body, NULL, NULL, NULL, NULL, NULL);
 
   for (; *template; template++)
 
   for (; *template; template++)
-    if (IS_ASM_LOGICAL_LINE_SEPARATOR (*template) || *template == '\n')
+    if (IS_ASM_LOGICAL_LINE_SEPARATOR (*template, template)
+       || *template == '\n')
       count++;
 
   return count;
 }
 #endif
 \f
       count++;
 
   return count;
 }
 #endif
 \f
+/* ??? This is probably the wrong place for these.  */
+/* Structure recording the mapping from source file and directory
+   names at compile time to those to be embedded in debug
+   information.  */
+typedef struct debug_prefix_map
+{
+  const char *old_prefix;
+  const char *new_prefix;
+  size_t old_len;
+  size_t new_len;
+  struct debug_prefix_map *next;
+} debug_prefix_map;
+
+/* Linked list of such structures.  */
+debug_prefix_map *debug_prefix_maps;
+
+
+/* Record a debug file prefix mapping.  ARG is the argument to
+   -fdebug-prefix-map and must be of the form OLD=NEW.  */
+
+void
+add_debug_prefix_map (const char *arg)
+{
+  debug_prefix_map *map;
+  const char *p;
+
+  p = strchr (arg, '=');
+  if (!p)
+    {
+      error ("invalid argument %qs to -fdebug-prefix-map", arg);
+      return;
+    }
+  map = XNEW (debug_prefix_map);
+  map->old_prefix = ggc_alloc_string (arg, p - arg);
+  map->old_len = p - arg;
+  p++;
+  map->new_prefix = ggc_strdup (p);
+  map->new_len = strlen (p);
+  map->next = debug_prefix_maps;
+  debug_prefix_maps = map;
+}
+
+/* Perform user-specified mapping of debug filename prefixes.  Return
+   the new name corresponding to FILENAME.  */
+
+const char *
+remap_debug_filename (const char *filename)
+{
+  debug_prefix_map *map;
+  char *s;
+  const char *name;
+  size_t name_len;
+
+  for (map = debug_prefix_maps; map; map = map->next)
+    if (strncmp (filename, map->old_prefix, map->old_len) == 0)
+      break;
+  if (!map)
+    return filename;
+  name = filename + map->old_len;
+  name_len = strlen (name) + 1;
+  s = (char *) alloca (name_len + map->new_len);
+  memcpy (s, map->new_prefix, map->new_len);
+  memcpy (s + map->new_len, name, name_len);
+  return ggc_strdup (s);
+}
+\f
 /* Output assembler code for the start of a function,
    and initialize some of the variables in this file
    for the new function.  The label for the function and associated
 /* Output assembler code for the start of a function,
    and initialize some of the variables in this file
    for the new function.  The label for the function and associated
@@ -1347,7 +1492,7 @@ final_start_function (rtx first ATTRIBUTE_UNUSED, FILE *file,
 
   (*debug_hooks->begin_prologue) (last_linenum, last_filename);
 
 
   (*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
@@ -1360,20 +1505,19 @@ final_start_function (rtx first ATTRIBUTE_UNUSED, FILE *file,
   /* The Sun386i and perhaps other machines don't work right
      if the profiling code comes after the prologue.  */
 #ifdef PROFILE_BEFORE_PROLOGUE
   /* The Sun386i and perhaps other machines don't work right
      if the profiling code comes after the prologue.  */
 #ifdef PROFILE_BEFORE_PROLOGUE
-  if (current_function_profile)
+  if (crtl->profile)
     profile_function (file);
 #endif /* PROFILE_BEFORE_PROLOGUE */
 
 #if defined (DWARF2_UNWIND_INFO) && defined (HAVE_prologue)
   if (dwarf2out_do_frame ())
     profile_function (file);
 #endif /* PROFILE_BEFORE_PROLOGUE */
 
 #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
      function.  */
   if (write_symbols)
     {
 #endif
 
   /* If debugging, assign block numbers to all of the blocks in this
      function.  */
   if (write_symbols)
     {
-      remove_unnecessary_notes ();
       reemit_insn_block_notes ();
       number_blocks (current_function_decl);
       /* We never actually put out begin/end notes for the top-level
       reemit_insn_block_notes ();
       number_blocks (current_function_decl);
       /* We never actually put out begin/end notes for the top-level
@@ -1382,6 +1526,15 @@ final_start_function (rtx first ATTRIBUTE_UNUSED, FILE *file,
       TREE_ASM_WRITTEN (DECL_INITIAL (current_function_decl)) = 1;
     }
 
       TREE_ASM_WRITTEN (DECL_INITIAL (current_function_decl)) = 1;
     }
 
+  if (warn_frame_larger_than
+    && get_frame_size () > frame_larger_than_size)
+  {
+      /* Issue a warning */
+      warning (OPT_Wframe_larger_than_,
+               "the frame size of %wd bytes is larger than %wd bytes",
+               get_frame_size (), frame_larger_than_size);
+  }
+
   /* First output the function prologue: code to set up the stack frame.  */
   targetm.asm_out.function_prologue (file, get_frame_size ());
 
   /* First output the function prologue: code to set up the stack frame.  */
   targetm.asm_out.function_prologue (file, get_frame_size ());
 
@@ -1397,7 +1550,7 @@ static void
 profile_after_prologue (FILE *file ATTRIBUTE_UNUSED)
 {
 #ifndef PROFILE_BEFORE_PROLOGUE
 profile_after_prologue (FILE *file ATTRIBUTE_UNUSED)
 {
 #ifndef PROFILE_BEFORE_PROLOGUE
-  if (current_function_profile)
+  if (crtl->profile)
     profile_function (file);
 #endif /* not PROFILE_BEFORE_PROLOGUE */
 }
     profile_function (file);
 #endif /* not PROFILE_BEFORE_PROLOGUE */
 }
@@ -1409,7 +1562,7 @@ profile_function (FILE *file ATTRIBUTE_UNUSED)
 # define NO_PROFILE_COUNTERS   0
 #endif
 #if defined(ASM_OUTPUT_REG_PUSH)
 # define NO_PROFILE_COUNTERS   0
 #endif
 #if defined(ASM_OUTPUT_REG_PUSH)
-  int sval = current_function_returns_struct;
+  int sval = cfun->returns_struct;
   rtx svrtx = targetm.calls.struct_value_rtx (TREE_TYPE (current_function_decl), 1);
 #if defined(STATIC_CHAIN_INCOMING_REGNUM) || defined(STATIC_CHAIN_REGNUM)
   int cxt = cfun->static_chain_decl != NULL;
   rtx svrtx = targetm.calls.struct_value_rtx (TREE_TYPE (current_function_decl), 1);
 #if defined(STATIC_CHAIN_INCOMING_REGNUM) || defined(STATIC_CHAIN_REGNUM)
   int cxt = cfun->static_chain_decl != NULL;
@@ -1419,17 +1572,19 @@ profile_function (FILE *file ATTRIBUTE_UNUSED)
   if (! NO_PROFILE_COUNTERS)
     {
       int align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
   if (! NO_PROFILE_COUNTERS)
     {
       int align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
-      data_section ();
+      switch_to_section (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);
     }
 
       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);
+  switch_to_section (current_function_section ());
 
 #if defined(ASM_OUTPUT_REG_PUSH)
 
 #if defined(ASM_OUTPUT_REG_PUSH)
-  if (sval && svrtx != NULL_RTX && GET_CODE (svrtx) == REG)
-    ASM_OUTPUT_REG_PUSH (file, REGNO (svrtx));
+  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)
@@ -1459,8 +1614,10 @@ profile_function (FILE *file ATTRIBUTE_UNUSED)
 #endif
 
 #if defined(ASM_OUTPUT_REG_PUSH)
 #endif
 
 #if defined(ASM_OUTPUT_REG_PUSH)
-  if (sval && svrtx != NULL_RTX && GET_CODE (svrtx) == REG)
-    ASM_OUTPUT_REG_POP (file, REGNO (svrtx));
+  if (sval && svrtx != NULL_RTX && REG_P (svrtx))
+    {
+      ASM_OUTPUT_REG_POP (file, REGNO (svrtx));
+    }
 #endif
 }
 
 #endif
 }
 
@@ -1490,18 +1647,10 @@ final_end_function (void)
 }
 \f
 /* Output assembler code for some insns: all or part of a function.
 }
 \f
 /* Output assembler code for some insns: all or part of a function.
-   For description of args, see `final_start_function', above.
-
-   PRESCAN is 1 if we are not really outputting,
-     just scanning as if we were outputting.
-   Prescanning deletes and rearranges insns just like ordinary output.
-   PRESCAN is -2 if we are outputting after having prescanned.
-   In this case, don't try to delete or rearrange insns
-   because that has already been done.
-   Prescanning is done only on certain machines.  */
+   For description of args, see `final_start_function', above.  */
 
 void
 
 void
-final (rtx first, FILE *file, int optimize, int prescan)
+final (rtx first, FILE *file, int optimize)
 {
   rtx insn;
   int max_uid = 0;
 {
   rtx insn;
   int max_uid = 0;
@@ -1509,28 +1658,6 @@ final (rtx first, FILE *file, int optimize, int prescan)
 
   last_ignored_compare = 0;
 
 
   last_ignored_compare = 0;
 
-#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.  */
-  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 (last != 0
-               && NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last)
-               && NOTE_SOURCE_FILE (insn) == NOTE_SOURCE_FILE (last))
-             {
-               delete_insn (insn);     /* Use delete_note.  */
-               continue;
-             }
-           last = insn;
-         }
-    }
-#endif
-
   for (insn = first; insn; insn = NEXT_INSN (insn))
     {
       if (INSN_UID (insn) > max_uid)       /* Find largest UID.  */
   for (insn = first; insn; insn = NEXT_INSN (insn))
     {
       if (INSN_UID (insn) > max_uid)       /* Find largest UID.  */
@@ -1538,7 +1665,7 @@ final (rtx first, FILE *file, int optimize, int prescan)
 #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)
@@ -1554,23 +1681,21 @@ final (rtx first, FILE *file, int optimize, int prescan)
   CC_STATUS_INIT;
 
   /* Output the insns.  */
   CC_STATUS_INIT;
 
   /* Output the insns.  */
-  for (insn = NEXT_INSN (first); insn;)
+  for (insn = first; insn;)
     {
 #ifdef HAVE_ATTR_length
       if ((unsigned) INSN_UID (insn) >= INSN_ADDRESSES_SIZE ())
        {
          /* This can be triggered by bugs elsewhere in the compiler if
             new insns are created after init_insn_lengths is called.  */
     {
 #ifdef HAVE_ATTR_length
       if ((unsigned) INSN_UID (insn) >= INSN_ADDRESSES_SIZE ())
        {
          /* 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, &seen);
+      insn = final_scan_insn (insn, file, optimize, 0, &seen);
     }
 }
 \f
     }
 }
 \f
@@ -1584,12 +1709,11 @@ get_insn_template (int code, rtx insn)
     case INSN_OUTPUT_FORMAT_MULTI:
       return insn_data[code].output.multi[which_alternative];
     case INSN_OUTPUT_FORMAT_FUNCTION:
     case INSN_OUTPUT_FORMAT_MULTI:
       return insn_data[code].output.multi[which_alternative];
     case INSN_OUTPUT_FORMAT_FUNCTION:
-      if (insn == NULL)
-       abort ();
+      gcc_assert (insn);
       return (*insn_data[code].output.function) (recog_data.operand, insn);
 
     default:
       return (*insn_data[code].output.function) (recog_data.operand, insn);
 
     default:
-      abort ();
+      gcc_unreachable ();
     }
 }
 
     }
 }
 
@@ -1620,37 +1744,8 @@ output_alternate_entry_point (FILE *file, rtx insn)
 
     case LABEL_NORMAL:
     default:
 
     case LABEL_NORMAL:
     default:
-      abort ();
-    }
-}
-
-/* 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 (GET_CODE (temp) == NOTE
-         && NOTE_LINE_NUMBER (temp) == NOTE_INSN_UNLIKELY_EXECUTED_CODE)
-       return true;
-      if (GET_CODE (temp) == NOTE
-         && NOTE_LINE_NUMBER (temp) == NOTE_INSN_BASIC_BLOCK)
-       {
-         bb_note_count++;
-         if (bb_note_count > 1)
-           return false;
-       }
-      if (INSN_P (temp))
-       return false;
+      gcc_unreachable ();
     }
     }
-  
-  return false;
 }
 
 /* The final scan for one insn, INSN.
 }
 
 /* The final scan for one insn, INSN.
@@ -1669,12 +1764,12 @@ scan_ahead_for_unlikely_executed_note (rtx insn)
 
 rtx
 final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
 
 rtx
 final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
-                int prescan, int nopeepholes ATTRIBUTE_UNUSED,
-                int *seen)
+                int nopeepholes ATTRIBUTE_UNUSED, int *seen)
 {
 #ifdef HAVE_cc0
   rtx set;
 #endif
 {
 #ifdef HAVE_cc0
   rtx set;
 #endif
+  rtx next;
 
   insn_counter++;
 
 
   insn_counter++;
 
@@ -1686,50 +1781,28 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
   switch (GET_CODE (insn))
     {
     case NOTE:
   switch (GET_CODE (insn))
     {
     case NOTE:
-      if (prescan > 0)
-       break;
-
-      switch (NOTE_LINE_NUMBER (insn))
+      switch (NOTE_KIND (insn))
        {
        case NOTE_INSN_DELETED:
        {
        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;
 
          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 ();
+       case NOTE_INSN_SWITCH_TEXT_SECTIONS:
+         in_cold_section_p = !in_cold_section_p;
+#ifdef DWARF2_UNWIND_INFO
+         if (dwarf2out_do_frame ())
+           dwarf2out_switch_text_section ();
+         else
+#endif
+           (*debug_hooks->switch_text_section) ();
+
+         switch_to_section (current_function_section ());
          break;
          break;
-         
+
        case NOTE_INSN_BASIC_BLOCK:
        case NOTE_INSN_BASIC_BLOCK:
-         
-         /* 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
-             && in_unlikely_text_section()
-             && !scan_ahead_for_unlikely_executed_note (insn))
-           text_section ();
-
-#ifdef IA64_UNWIND_INFO
-         IA64_UNWIND_EMIT (asm_out_file, insn);
+#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);
@@ -1737,7 +1810,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
          if ((*seen & (SEEN_EMITTED | SEEN_BB)) == SEEN_BB)
            {
              *seen |= SEEN_EMITTED;
          if ((*seen & (SEEN_EMITTED | SEEN_BB)) == SEEN_BB)
            {
              *seen |= SEEN_EMITTED;
-             last_filename = NULL;
+             force_source_line = true;
            }
          else
            *seen |= SEEN_BB;
            }
          else
            *seen |= SEEN_BB;
@@ -1761,7 +1834,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
          if ((*seen & (SEEN_EMITTED | SEEN_NOTE)) == SEEN_NOTE)
            {
              *seen |= SEEN_EMITTED;
          if ((*seen & (SEEN_EMITTED | SEEN_NOTE)) == SEEN_NOTE)
            {
              *seen |= SEEN_EMITTED;
-             last_filename = NULL;
+             force_source_line = true;
            }
          else
            *seen |= SEEN_NOTE;
            }
          else
            *seen |= SEEN_NOTE;
@@ -1779,7 +1852,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
          if ((*seen & (SEEN_EMITTED | SEEN_NOTE)) == SEEN_NOTE)
            {
              *seen |= SEEN_EMITTED;
          if ((*seen & (SEEN_EMITTED | SEEN_NOTE)) == SEEN_NOTE)
            {
              *seen |= SEEN_EMITTED;
-             last_filename = NULL;
+             force_source_line = true;
            }
          else
            *seen |= SEEN_NOTE;
            }
          else
            *seen |= SEEN_NOTE;
@@ -1789,7 +1862,6 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
        case NOTE_INSN_BLOCK_BEG:
          if (debug_info_level == DINFO_LEVEL_NORMAL
              || debug_info_level == DINFO_LEVEL_VERBOSE
        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)
@@ -1806,12 +1878,23 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
              /* Mark this block as output.  */
              TREE_ASM_WRITTEN (NOTE_BLOCK (insn)) = 1;
            }
              /* Mark this block as output.  */
              TREE_ASM_WRITTEN (NOTE_BLOCK (insn)) = 1;
            }
+         if (write_symbols == DBX_DEBUG
+             || write_symbols == SDB_DEBUG)
+           {
+             location_t *locus_ptr
+               = block_nonartificial_location (NOTE_BLOCK (insn));
+
+             if (locus_ptr != NULL)
+               {
+                 override_filename = LOCATION_FILE (*locus_ptr);
+                 override_linenum = LOCATION_LINE (*locus_ptr);
+               }
+           }
          break;
 
        case NOTE_INSN_BLOCK_END:
          if (debug_info_level == DINFO_LEVEL_NORMAL
              || debug_info_level == DINFO_LEVEL_VERBOSE
          break;
 
        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)
@@ -1822,11 +1905,28 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
 
              /* 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);
            }
+         if (write_symbols == DBX_DEBUG
+             || write_symbols == SDB_DEBUG)
+           {
+             tree outer_block = BLOCK_SUPERCONTEXT (NOTE_BLOCK (insn));
+             location_t *locus_ptr
+               = block_nonartificial_location (outer_block);
+
+             if (locus_ptr != NULL)
+               {
+                 override_filename = LOCATION_FILE (*locus_ptr);
+                 override_linenum = LOCATION_LINE (*locus_ptr);
+               }
+             else
+               {
+                 override_filename = NULL;
+                 override_linenum = 0;
+               }
+           }
          break;
 
        case NOTE_INSN_DELETED_LABEL:
          break;
 
        case NOTE_INSN_DELETED_LABEL:
@@ -1840,12 +1940,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
          (*debug_hooks->var_location) (insn);
          break;
 
          (*debug_hooks->var_location) (insn);
          break;
 
-       case 0:
-         break;
-
        default:
        default:
-         if (NOTE_LINE_NUMBER (insn) <= 0)
-           abort ();
+         gcc_unreachable ();
          break;
        }
       break;
          break;
        }
       break;
@@ -1853,7 +1949,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
     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;
 
@@ -1882,67 +1978,21 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
        }
 #ifdef HAVE_cc0
       CC_STATUS_INIT;
        }
 #ifdef HAVE_cc0
       CC_STATUS_INIT;
-      /* If this label is reached from only one place, set the condition
-        codes from the instruction just before the branch.  */
-
-      /* Disabled because some insns set cc_status in the C output code
-        and NOTICE_UPDATE_CC alone can set incorrect status.  */
-      if (0 /* optimize && LABEL_NUSES (insn) == 1*/)
-       {
-         rtx jump = LABEL_REFS (insn);
-         rtx barrier = prev_nonnote_insn (insn);
-         rtx prev;
-         /* If the LABEL_REFS field of this label has been set to point
-            at a branch, the predecessor of the branch is a regular
-            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
-             && (prev = prev_nonnote_insn (jump))
-             && GET_CODE (prev) == INSN)
-           {
-             NOTICE_UPDATE_CC (PATTERN (prev), prev);
-             NOTICE_UPDATE_CC (PATTERN (jump), jump);
-           }
-       }
 #endif
 #endif
-      if (prescan > 0)
-       break;
 
       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)
-       {
-         rtx tmp_table, tmp_label;
-         if (GET_CODE (insn) == CODE_LABEL
-             && 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 ())
-               text_section ();
-           }
-       }
-
       if (app_on)
        {
          fputs (ASM_APP_OFF, file);
          app_on = 0;
        }
       if (app_on)
        {
          fputs (ASM_APP_OFF, file);
          app_on = 0;
        }
-      if (NEXT_INSN (insn) != 0
-         && GET_CODE (NEXT_INSN (insn)) == JUMP_INSN)
+
+      next = next_nonnote_insn (insn);
+      if (next != 0 && JUMP_P (next))
        {
        {
-         rtx nextbody = PATTERN (NEXT_INSN (insn));
+         rtx nextbody = PATTERN (next);
 
          /* If this label is followed by a jump-table,
             make sure we put the label in the read-only section.  Also
 
          /* If this label is followed by a jump-table,
             make sure we put the label in the read-only section.  Also
@@ -1960,21 +2010,22 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
                {
                  int log_align;
 
                {
                  int log_align;
 
-                 readonly_data_section ();
+                 switch_to_section (targetm.asm_out.function_rodata_section
+                                    (current_function_decl));
 
 #ifdef ADDR_VEC_ALIGN
 
 #ifdef ADDR_VEC_ALIGN
-                 log_align = ADDR_VEC_ALIGN (NEXT_INSN (insn));
+                 log_align = ADDR_VEC_ALIGN (next);
 #else
                  log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT);
 #endif
                  ASM_OUTPUT_ALIGN (file, log_align);
                }
              else
 #else
                  log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT);
 #endif
                  ASM_OUTPUT_ALIGN (file, log_align);
                }
              else
-               function_section (current_function_decl);
+               switch_to_section (current_function_section ());
 
 #ifdef ASM_OUTPUT_CASE_LABEL
              ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
 
 #ifdef ASM_OUTPUT_CASE_LABEL
              ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
-                                    NEXT_INSN (insn));
+                                    next);
 #else
              targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
 #endif
 #else
              targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
 #endif
@@ -1993,8 +2044,11 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
        rtx body = PATTERN (insn);
        int insn_code_number;
        const char *template;
        rtx body = PATTERN (insn);
        int insn_code_number;
        const char *template;
-       rtx note;
 
 
+#ifdef HAVE_conditional_execution
+       /* Reset this early so it is correct for ASM statements.  */
+       current_insn_predicate = NULL_RTX;
+#endif
        /* 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.  */
 
@@ -2003,17 +2057,19 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
          break;
 
 #ifdef HAVE_cc0
          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
@@ -2025,8 +2081,11 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
            int vlen, idx;
 #endif
 
            int vlen, idx;
 #endif
 
-           if (prescan > 0)
-             break;
+           if (! JUMP_TABLES_IN_TEXT_SECTION)
+             switch_to_section (targetm.asm_out.function_rodata_section
+                                (current_function_decl));
+           else
+             switch_to_section (current_function_section ());
 
            if (app_on)
              {
 
            if (app_on)
              {
@@ -2040,7 +2099,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
 #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
@@ -2048,7 +2107,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
 #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
@@ -2061,7 +2120,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
                    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
@@ -2073,7 +2132,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
                       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
                  }
              }
@@ -2084,7 +2143,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
 #endif
 #endif
 
 #endif
 #endif
 
-           function_section (current_function_decl);
+           switch_to_section (current_function_section ());
 
            break;
          }
 
            break;
          }
@@ -2101,17 +2160,25 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
 
            /* There's no telling what that did to the condition codes.  */
            CC_STATUS_INIT;
 
            /* There's no telling what that did to the condition codes.  */
            CC_STATUS_INIT;
-           if (prescan > 0)
-             break;
 
            if (string[0])
              {
 
            if (string[0])
              {
+               expanded_location loc;
+
                if (! app_on)
                  {
                    fputs (ASM_APP_ON, file);
                    app_on = 1;
                  }
                if (! app_on)
                  {
                    fputs (ASM_APP_ON, file);
                    app_on = 1;
                  }
+               loc = expand_location (ASM_INPUT_SOURCE_LOCATION (body));
+               if (*loc.file && loc.line)
+                 fprintf (asm_out_file, "%s %i \"%s\" 1\n",
+                          ASM_COMMENT_START, loc.line, loc.file);
                fprintf (asm_out_file, "\t%s\n", string);
                fprintf (asm_out_file, "\t%s\n", string);
+#if HAVE_AS_LINE_ZERO
+               if (*loc.file && loc.line)
+                 fprintf (asm_out_file, "%s 0 \"\" 2\n", ASM_COMMENT_START);
+#endif
              }
            break;
          }
              }
            break;
          }
@@ -2122,17 +2189,18 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
            unsigned int noperands = asm_noperands (body);
            rtx *ops = alloca (noperands * sizeof (rtx));
            const char *string;
            unsigned int noperands = asm_noperands (body);
            rtx *ops = alloca (noperands * sizeof (rtx));
            const char *string;
+           location_t loc;
+           expanded_location expanded;
 
            /* There's no telling what that did to the condition codes.  */
            CC_STATUS_INIT;
 
            /* There's no telling what that did to the condition codes.  */
            CC_STATUS_INIT;
-           if (prescan > 0)
-             break;
 
            /* Get out the operand values.  */
 
            /* Get out the operand values.  */
-           string = decode_asm_operands (body, ops, NULL, NULL, NULL);
-           /* Inhibit aborts on what would otherwise be compiler bugs.  */
+           string = decode_asm_operands (body, ops, NULL, NULL, NULL, &loc);
+           /* Inhibit dying on what would otherwise be compiler bugs.  */
            insn_noperands = noperands;
            this_is_asm_operands = insn;
            insn_noperands = noperands;
            this_is_asm_operands = insn;
+           expanded = expand_location (loc);
 
 #ifdef FINAL_PRESCAN_INSN
            FINAL_PRESCAN_INSN (insn, ops, insn_noperands);
 
 #ifdef FINAL_PRESCAN_INSN
            FINAL_PRESCAN_INSN (insn, ops, insn_noperands);
@@ -2146,14 +2214,21 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
                    fputs (ASM_APP_ON, file);
                    app_on = 1;
                  }
                    fputs (ASM_APP_ON, file);
                    app_on = 1;
                  }
+               if (expanded.file && expanded.line)
+                 fprintf (asm_out_file, "%s %i \"%s\" 1\n",
+                          ASM_COMMENT_START, expanded.line, expanded.file);
                output_asm_insn (string, ops);
                output_asm_insn (string, ops);
+#if HAVE_AS_LINE_ZERO
+               if (expanded.file && expanded.line)
+                 fprintf (asm_out_file, "%s 0 \"\" 2\n", ASM_COMMENT_START);
+#endif
              }
 
            this_is_asm_operands = 0;
            break;
          }
 
              }
 
            this_is_asm_operands = 0;
            break;
          }
 
-       if (prescan <= 0 && app_on)
+       if (app_on)
          {
            fputs (ASM_APP_OFF, file);
            app_on = 0;
          {
            fputs (ASM_APP_OFF, file);
            app_on = 0;
@@ -2163,10 +2238,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
          {
            /* A delayed-branch sequence */
            int i;
          {
            /* A delayed-branch sequence */
            int i;
-           rtx next;
 
 
-           if (prescan > 0)
-             break;
            final_sequence = body;
 
            /* Record the delay slots' frame information before the branch.
            final_sequence = body;
 
            /* Record the delay slots' frame information before the branch.
@@ -2174,7 +2246,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
 #if defined (DWARF2_UNWIND_INFO)
            if (dwarf2out_do_frame ())
              for (i = 1; i < XVECLEN (body, 0); i++)
 #if defined (DWARF2_UNWIND_INFO)
            if (dwarf2out_do_frame ())
              for (i = 1; i < XVECLEN (body, 0); i++)
-               dwarf2out_frame_debug (XVECEXP (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
 #endif
 
            /* The first insn in this SEQUENCE might be a JUMP_INSN that will
@@ -2182,7 +2254,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
               thought unnecessary.  If that happens, cancel this sequence
               and cause that insn to be restored.  */
 
               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, seen);
+           next = final_scan_insn (XVECEXP (body, 0, 0), file, 0, 1, seen);
            if (next != XVECEXP (body, 0, 1))
              {
                final_sequence = 0;
            if (next != XVECEXP (body, 0, 1))
              {
                final_sequence = 0;
@@ -2196,7 +2268,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
                /* 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, seen);
+                 insn = final_scan_insn (insn, file, 0, 1, seen);
                while (insn != next);
              }
 #ifdef DBR_OUTPUT_SEQEND
                while (insn != next);
              }
 #ifdef DBR_OUTPUT_SEQEND
@@ -2209,7 +2281,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
               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;
              }
@@ -2267,20 +2339,6 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
          }
 #endif
 
          }
 #endif
 
-#ifndef STACK_REGS
-       /* Don't bother outputting obvious no-ops, even without -O.
-          This optimization is fast and doesn't interfere with debugging.
-          Don't do this if the insn is in a delay slot, since this
-          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
-           && REGNO (SET_SRC (body)) == REGNO (SET_DEST (body)))
-         break;
-#endif
-
 #ifdef HAVE_cc0
        /* If this is a conditional branch, maybe modify it
           if the cc's are in a nonstandard state
 #ifdef HAVE_cc0
        /* If this is a conditional branch, maybe modify it
           if the cc's are in a nonstandard state
@@ -2288,15 +2346,12 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
           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
            && COMPARISON_P (XEXP (SET_SRC (body), 0))
            && GET_CODE (body) == SET
            && SET_DEST (body) == pc_rtx
            && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE
            && 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.  */
-           && prescan >= 0)
+           && XEXP (XEXP (SET_SRC (body), 0), 0) == cc0_rtx)
          {
            /* This function may alter the contents of its argument
               and clear some of the cc_status.flags bits.
          {
            /* This function may alter the contents of its argument
               and clear some of the cc_status.flags bits.
@@ -2328,6 +2383,41 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
              INSN_CODE (insn) = -1;
          }
 
              INSN_CODE (insn) = -1;
          }
 
+       /* If this is a conditional trap, maybe modify it if the cc's
+          are in a nonstandard state so that it accomplishes the same
+          thing that it would do straightforwardly if the cc's were
+          set up normally.  */
+       if (cc_status.flags != 0
+           && NONJUMP_INSN_P (insn)
+           && GET_CODE (body) == TRAP_IF
+           && COMPARISON_P (TRAP_CONDITION (body))
+           && XEXP (TRAP_CONDITION (body), 0) == cc0_rtx)
+         {
+           /* This function may alter the contents of its argument
+              and clear some of the cc_status.flags bits.
+              It may also return 1 meaning condition now always true
+              or -1 meaning condition now always false
+              or 2 meaning condition nontrivial but altered.  */
+           int result = alter_cond (TRAP_CONDITION (body));
+
+           /* If TRAP_CONDITION has become always false, delete the
+              instruction.  */
+           if (result == -1)
+             {
+               delete_insn (insn);
+               break;
+             }
+
+           /* If TRAP_CONDITION has become always true, replace
+              TRAP_CONDITION with const_true_rtx.  */
+           if (result == 1)
+             TRAP_CONDITION (body) = const_true_rtx;
+
+           /* Rerecognize the instruction if it has changed.  */
+           if (result != 0)
+             INSN_CODE (insn) = -1;
+         }
+
        /* Make same adjustments to instructions that examine the
           condition codes without jumping and instructions that
           handle conditional moves (if this machine has either one).  */
        /* Make same adjustments to instructions that examine the
           condition codes without jumping and instructions that
           handle conditional moves (if this machine has either one).  */
@@ -2337,7 +2427,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
          {
            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);
@@ -2396,14 +2486,16 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
               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, seen);
+                 final_scan_insn (note, file, optimize, nopeepholes, seen);
 
 
-               /* In case this is prescan, put the notes
-                  in proper position for later rescan.  */
+               /* Put the notes in the proper position for a later
+                  rescan.  For example, the SH target can do this
+                  when generating a far jump in a delayed branch
+                  sequence.  */
                note = NEXT_INSN (insn);
                PREV_INSN (note) = prev;
                NEXT_INSN (prev) = note;
                note = NEXT_INSN (insn);
                PREV_INSN (note) = prev;
                NEXT_INSN (prev) = note;
@@ -2447,8 +2539,6 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
 #ifdef HAVE_conditional_execution
        if (GET_CODE (PATTERN (insn)) == COND_EXEC)
          current_insn_predicate = COND_EXEC_TEST (PATTERN (insn));
 #ifdef HAVE_conditional_execution
        if (GET_CODE (PATTERN (insn)) == COND_EXEC)
          current_insn_predicate = COND_EXEC_TEST (PATTERN (insn));
-       else
-         current_insn_predicate = NULL_RTX;
 #endif
 
 #ifdef HAVE_cc0
 #endif
 
 #ifdef HAVE_cc0
@@ -2465,8 +2555,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
        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.  */
@@ -2479,8 +2569,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
          {
            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
@@ -2490,7 +2579,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
                 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.  */
              }
 
@@ -2511,64 +2600,65 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
            /* 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;
          }
 
-       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);
 
        /* 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)
        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 (GET_CODE (insn) == INSN
+       if (final_sequence == 0
 #if !defined (HAVE_prologue)
            && !ACCUMULATE_OUTGOING_ARGS
 #endif
 #if !defined (HAVE_prologue)
            && !ACCUMULATE_OUTGOING_ARGS
 #endif
-           && final_sequence == 0
            && dwarf2out_do_frame ())
            && dwarf2out_do_frame ())
-         dwarf2out_frame_debug (insn);
-#endif
-
-#if 0
-       /* It's not at all clear why we did this and doing so used to
-          interfere with tests that used REG_WAS_0 notes, which are
-          now gone, so let's try with this out.  */
-
-       /* Mark this insn as having been output.  */
-       INSN_DELETED_P (insn) = 1;
+         dwarf2out_frame_debug (insn, true);
 #endif
 
 #endif
 
-       /* Emit information for vtable gc.  */
-       note = find_reg_note (insn, REG_VTABLE_REF, NULL_RTX);
-
        current_output_insn = debug_insn = 0;
       }
     }
   return NEXT_INSN (insn);
 }
 \f
        current_output_insn = debug_insn = 0;
       }
     }
   return NEXT_INSN (insn);
 }
 \f
-/* Output debugging info to the assembler file FILE
-   based on the NOTE-insn INSN, assumed to be a line number.  */
+/* Return whether a source line note needs to be emitted before INSN.  */
 
 static bool
 notice_source_line (rtx insn)
 {
 
 static bool
 notice_source_line (rtx insn)
 {
-  const char *filename = insn_file (insn);
-  int linenum = insn_line (insn);
+  const char *filename;
+  int linenum;
+
+  if (override_filename)
+    {
+      filename = override_filename;
+      linenum = override_linenum;
+    }
+  else
+    {
+      filename = insn_file (insn);
+      linenum = insn_line (insn);
+    }
 
 
-  if (filename && (filename != last_filename || last_linenum != linenum))
+  if (filename
+      && (force_source_line
+         || filename != last_filename
+         || last_linenum != linenum))
     {
     {
+      force_source_line = false;
       last_filename = filename;
       last_linenum = linenum;
       high_block_linenum = MAX (last_linenum, high_block_linenum);
       last_filename = filename;
       last_linenum = linenum;
       high_block_linenum = MAX (last_linenum, high_block_linenum);
@@ -2585,6 +2675,7 @@ void
 cleanup_subreg_operands (rtx insn)
 {
   int i;
 cleanup_subreg_operands (rtx insn)
 {
   int i;
+  bool changed = false;
   extract_insn_cached (insn);
   for (i = 0; i < recog_data.n_operands; i++)
     {
   extract_insn_cached (insn);
   for (i = 0; i < recog_data.n_operands; i++)
     {
@@ -2594,22 +2685,30 @@ cleanup_subreg_operands (rtx insn)
         matches the else clause.  Instead we test the underlying
         expression directly.  */
       if (GET_CODE (*recog_data.operand_loc[i]) == SUBREG)
         matches the else clause.  Instead we test the underlying
         expression directly.  */
       if (GET_CODE (*recog_data.operand_loc[i]) == SUBREG)
-       recog_data.operand[i] = alter_subreg (recog_data.operand_loc[i]);
+       {
+         recog_data.operand[i] = alter_subreg (recog_data.operand_loc[i]);
+         changed = true;
+       }
       else if (GET_CODE (recog_data.operand[i]) == PLUS
               || GET_CODE (recog_data.operand[i]) == MULT
       else if (GET_CODE (recog_data.operand[i]) == PLUS
               || GET_CODE (recog_data.operand[i]) == MULT
-              || GET_CODE (recog_data.operand[i]) == MEM)
-       recog_data.operand[i] = walk_alter_subreg (recog_data.operand_loc[i]);
+              || MEM_P (recog_data.operand[i]))
+       recog_data.operand[i] = walk_alter_subreg (recog_data.operand_loc[i], &changed);
     }
 
   for (i = 0; i < recog_data.n_dups; i++)
     {
       if (GET_CODE (*recog_data.dup_loc[i]) == SUBREG)
     }
 
   for (i = 0; i < recog_data.n_dups; i++)
     {
       if (GET_CODE (*recog_data.dup_loc[i]) == SUBREG)
-       *recog_data.dup_loc[i] = alter_subreg (recog_data.dup_loc[i]);
+       {
+         *recog_data.dup_loc[i] = alter_subreg (recog_data.dup_loc[i]);
+         changed = true;
+       }
       else if (GET_CODE (*recog_data.dup_loc[i]) == PLUS
               || GET_CODE (*recog_data.dup_loc[i]) == MULT
       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)
-       *recog_data.dup_loc[i] = walk_alter_subreg (recog_data.dup_loc[i]);
+              || MEM_P (*recog_data.dup_loc[i]))
+       *recog_data.dup_loc[i] = walk_alter_subreg (recog_data.dup_loc[i], &changed);
     }
     }
+  if (changed)
+    df_insn_rescan (insn);
 }
 
 /* If X is a SUBREG, replace it with a REG or a MEM,
 }
 
 /* If X is a SUBREG, replace it with a REG or a MEM,
@@ -2623,8 +2722,25 @@ alter_subreg (rtx *xp)
 
   /* simplify_subreg does not remove subreg from volatile references.
      We are required to.  */
 
   /* 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),
@@ -2632,14 +2748,19 @@ alter_subreg (rtx *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 if (REG_P (y))
        {
        {
-         unsigned int regno = subreg_hard_regno (x, 1);
-         *xp = gen_rtx_REG_offset (y, GET_MODE (x), regno, SUBREG_BYTE (x));
+         /* Simplify_subreg can't handle some REG cases, but we have to.  */
+         unsigned int regno;
+         HOST_WIDE_INT offset;
+
+         regno = subreg_regno (x);
+         if (subreg_lowpart_p (x))
+           offset = byte_lowpart_offset (GET_MODE (x), GET_MODE (y));
+         else
+           offset = SUBREG_BYTE (x);
+         *xp = gen_rtx_REG_offset (y, GET_MODE (x), regno, offset);
        }
        }
-      else
-       abort ();
     }
 
   return *xp;
     }
 
   return *xp;
@@ -2648,22 +2769,25 @@ alter_subreg (rtx *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 (rtx *xp)
+walk_alter_subreg (rtx *xp, bool *changed)
 {
   rtx x = *xp;
   switch (GET_CODE (x))
     {
     case PLUS:
     case MULT:
 {
   rtx x = *xp;
   switch (GET_CODE (x))
     {
     case PLUS:
     case MULT:
-      XEXP (x, 0) = walk_alter_subreg (&XEXP (x, 0));
-      XEXP (x, 1) = walk_alter_subreg (&XEXP (x, 1));
+    case AND:
+      XEXP (x, 0) = walk_alter_subreg (&XEXP (x, 0), changed);
+      XEXP (x, 1) = walk_alter_subreg (&XEXP (x, 1), changed);
       break;
 
     case MEM:
       break;
 
     case MEM:
-      XEXP (x, 0) = walk_alter_subreg (&XEXP (x, 0));
+    case ZERO_EXTEND:
+      XEXP (x, 0) = walk_alter_subreg (&XEXP (x, 0), changed);
       break;
 
     case SUBREG:
       break;
 
     case SUBREG:
+      *changed = true;
       return alter_subreg (xp);
 
     default:
       return alter_subreg (xp);
 
     default:
@@ -2788,7 +2912,7 @@ alter_cond (rtx 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);
@@ -2838,17 +2962,17 @@ alter_cond (rtx 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 (const char *msgid, ...)
+output_operand_lossage (const char *cmsgid, ...)
 {
   char *fmt_string;
   char *new_message;
   const char *pfx_str;
   va_list ap;
 
 {
   char *fmt_string;
   char *new_message;
   const char *pfx_str;
   va_list ap;
 
-  va_start (ap, msgid);
+  va_start (ap, cmsgid);
 
 
-  pfx_str = this_is_asm_operands ? _("invalid `asm': ") : "output_operand: ";
-  asprintf (&fmt_string, "%s%s", pfx_str, _(msgid));
+  pfx_str = this_is_asm_operands ? _("invalid 'asm': ") : "output_operand: ";
+  asprintf (&fmt_string, "%s%s", pfx_str, _(cmsgid));
   vasprintf (&new_message, fmt_string, ap);
 
   if (this_is_asm_operands)
   vasprintf (&new_message, fmt_string, ap);
 
   if (this_is_asm_operands)
@@ -2899,9 +3023,9 @@ get_mem_expr_from_op (rtx op, int *paddressp)
 
   *paddressp = 0;
 
 
   *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)
@@ -3100,61 +3224,66 @@ output_asm_insn (const char *template, rtx *operands)
        else if (ISALPHA (*p))
          {
            int letter = *p++;
        else if (ISALPHA (*p))
          {
            int letter = *p++;
-           c = atoi (p);
+           unsigned long opnum;
+           char *endptr;
+
+           opnum = strtoul (p, &endptr, 10);
 
 
-           if (! ISDIGIT (*p))
-             output_operand_lossage ("operand number missing after %%-letter");
-           else if (this_is_asm_operands
-                    && (c < 0 || (unsigned int) c >= insn_noperands))
+           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.
@@ -3189,12 +3318,12 @@ output_asm_label (rtx x)
 
   if (GET_CODE (x) == LABEL_REF)
     x = XEXP (x, 0);
 
   if (GET_CODE (x) == LABEL_REF)
     x = XEXP (x, 0);
-  if (GET_CODE (x) == CODE_LABEL
-      || (GET_CODE (x) == NOTE
-         && NOTE_LINE_NUMBER (x) == NOTE_INSN_DELETED_LABEL))
+  if (LABEL_P (x)
+      || (NOTE_P (x)
+         && NOTE_KIND (x) == NOTE_INSN_DELETED_LABEL))
     ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
   else
     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);
 }
@@ -3215,11 +3344,8 @@ output_operand (rtx x, int code ATTRIBUTE_UNUSED)
   if (x && GET_CODE (x) == SUBREG)
     x = alter_subreg (&x);
 
   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 ();
+  /* X must not be a pseudo reg.  */
+  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);
 }
@@ -3231,7 +3357,8 @@ output_operand (rtx x, int code ATTRIBUTE_UNUSED)
 void
 output_address (rtx x)
 {
 void
 output_address (rtx x)
 {
-  walk_alter_subreg (&x);
+  bool changed = false;
+  walk_alter_subreg (&x, &changed);
   PRINT_OPERAND_ADDRESS (asm_out_file, x);
 }
 \f
   PRINT_OPERAND_ADDRESS (asm_out_file, x);
 }
 \f
@@ -3289,9 +3416,11 @@ output_addr_const (FILE *file, rtx x)
          /* We can use %d if the number is one word and positive.  */
          if (CONST_DOUBLE_HIGH (x))
            fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
          /* We can use %d if the number is one word and positive.  */
          if (CONST_DOUBLE_HIGH (x))
            fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
-                    CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
+                    (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x),
+                    (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x));
          else if (CONST_DOUBLE_LOW (x) < 0)
          else if (CONST_DOUBLE_LOW (x) < 0)
-           fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (x));
+           fprintf (file, HOST_WIDE_INT_PRINT_HEX,
+                    (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x));
          else
            fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
        }
          else
            fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
        }
@@ -3301,6 +3430,11 @@ output_addr_const (FILE *file, rtx x)
        output_operand_lossage ("floating constant misused");
       break;
 
        output_operand_lossage ("floating constant misused");
       break;
 
+    case CONST_FIXED:
+      fprintf (file, HOST_WIDE_INT_PRINT_HEX,
+              (unsigned HOST_WIDE_INT) CONST_FIXED_VALUE_LOW (x));
+      break;
+
     case PLUS:
       /* Some assemblers need integer constants to appear last (eg masm).  */
       if (GET_CODE (XEXP (x, 0)) == CONST_INT)
     case PLUS:
       /* Some assemblers need integer constants to appear last (eg masm).  */
       if (GET_CODE (XEXP (x, 0)) == CONST_INT)
@@ -3344,6 +3478,7 @@ output_addr_const (FILE *file, rtx x)
     case ZERO_EXTEND:
     case SIGN_EXTEND:
     case SUBREG:
     case ZERO_EXTEND:
     case SIGN_EXTEND:
     case SUBREG:
+    case TRUNCATE:
       output_addr_const (file, XEXP (x, 0));
       break;
 
       output_addr_const (file, XEXP (x, 0));
       break;
 
@@ -3518,7 +3653,7 @@ asm_fprintf (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;
 
          }
        break;
 
@@ -3665,8 +3800,8 @@ split_double (rtx value, rtx *first, rtx *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
     }
 }
 \f
@@ -3678,32 +3813,32 @@ leaf_function_p (void)
   rtx insn;
   rtx link;
 
   rtx insn;
   rtx link;
 
-  if (current_function_profile || profile_arc_flag)
+  if (crtl->profile || profile_arc_flag)
     return 0;
 
   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
     {
     return 0;
 
   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;
     }
-  for (link = current_function_epilogue_delay_list;
+  for (link = crtl->epilogue_delay_list;
        link;
        link = XEXP (link, 1))
     {
       insn = XEXP (link, 0);
 
        link;
        link = XEXP (link, 1))
     {
       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;
     }
@@ -3719,13 +3854,12 @@ int
 final_forward_branch_p (rtx insn)
 {
   int insn_id, label_id;
 final_forward_branch_p (rtx insn)
 {
   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;
 }
 
@@ -3750,13 +3884,13 @@ only_leaf_regs_used (void)
   const char *const permitted_reg_in_leaf_functions = LEAF_REGISTERS;
 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
   const char *const permitted_reg_in_leaf_functions = LEAF_REGISTERS;
 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    if ((regs_ever_live[i] || global_regs[i])
+    if ((df_regs_ever_live_p (i) || global_regs[i])
        && ! permitted_reg_in_leaf_functions[i])
       return 0;
 
        && ! permitted_reg_in_leaf_functions[i])
       return 0;
 
-  if (current_function_uses_pic_offset_table
+  if (crtl->uses_pic_offset_table
       && pic_offset_table_rtx != 0
       && 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;
 
@@ -3777,7 +3911,7 @@ leaf_renumber_regs (rtx first)
   for (insn = first; insn; insn = NEXT_INSN (insn))
     if (INSN_P (insn))
       leaf_renumber_regs_insn (PATTERN (insn));
   for (insn = first; insn; insn = NEXT_INSN (insn))
     if (INSN_P (insn))
       leaf_renumber_regs_insn (PATTERN (insn));
-  for (insn = current_function_epilogue_delay_list;
+  for (insn = crtl->epilogue_delay_list;
        insn;
        insn = XEXP (insn, 1))
     if (INSN_P (XEXP (insn, 0)))
        insn;
        insn = XEXP (insn, 1))
     if (INSN_P (XEXP (insn, 0)))
@@ -3800,7 +3934,7 @@ leaf_renumber_regs_insn (rtx 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;
 
@@ -3817,11 +3951,10 @@ leaf_renumber_regs_insn (rtx in_rtx)
          return;
        }
       newreg = LEAF_REG_REMAP (newreg);
          return;
        }
       newreg = LEAF_REG_REMAP (newreg);
-      if (newreg < 0)
-       abort ();
-      regs_ever_live[REGNO (in_rtx)] = 0;
-      regs_ever_live[newreg] = 1;
-      REGNO (in_rtx) = newreg;
+      gcc_assert (newreg >= 0);
+      df_set_regs_ever_live (REGNO (in_rtx), false);
+      df_set_regs_ever_live (newreg, true);
+      SET_REGNO (in_rtx, newreg);
       in_rtx->used = 1;
     }
 
       in_rtx->used = 1;
     }
 
@@ -3861,7 +3994,7 @@ leaf_renumber_regs_insn (rtx in_rtx)
        break;
 
       default:
        break;
 
       default:
-       abort ();
+       gcc_unreachable ();
       }
 }
 #endif
       }
 }
 #endif
@@ -3897,7 +4030,7 @@ debug_flush_symbol_queue (void)
 
   for (i = 0; i < symbol_queue_index; ++i)
     {
 
   for (i = 0; i < symbol_queue_index; ++i)
     {
-      /* If we pushed queued symbols then such symbols are must be
+      /* If we pushed queued symbols then such symbols 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
          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
@@ -3947,3 +4080,204 @@ debug_free_queue (void)
       symbol_queue_size = 0;
     }
 }
       symbol_queue_size = 0;
     }
 }
+\f
+/* Turn the RTL into assembly.  */
+static unsigned int
+rest_of_handle_final (void)
+{
+  rtx x;
+  const char *fnname;
+
+  /* Get the function's name, as described by its RTL.  This may be
+     different from the DECL_NAME name used in the source file.  */
+
+  x = DECL_RTL (current_function_decl);
+  gcc_assert (MEM_P (x));
+  x = XEXP (x, 0);
+  gcc_assert (GET_CODE (x) == SYMBOL_REF);
+  fnname = XSTR (x, 0);
+
+  assemble_start_function (current_function_decl, fnname);
+  final_start_function (get_insns (), asm_out_file, optimize);
+  final (get_insns (), asm_out_file, optimize);
+  final_end_function ();
+
+#ifdef TARGET_UNWIND_INFO
+  /* ??? The IA-64 ".handlerdata" directive must be issued before
+     the ".endp" directive that closes the procedure descriptor.  */
+  output_function_exception_table (fnname);
+#endif
+
+  assemble_end_function (current_function_decl, fnname);
+
+#ifndef TARGET_UNWIND_INFO
+  /* Otherwise, it feels unclean to switch sections in the middle.  */
+  output_function_exception_table (fnname);
+#endif
+
+  user_defined_section_attribute = false;
+
+  /* Free up reg info memory.  */
+  free_reg_info ();
+
+  if (! quiet_flag)
+    fflush (asm_out_file);
+
+  /* Write DBX symbols if requested.  */
+
+  /* Note that for those inline functions where we don't initially
+     know for certain that we will be generating an out-of-line copy,
+     the first invocation of this routine (rest_of_compilation) will
+     skip over this code by doing a `goto exit_rest_of_compilation;'.
+     Later on, wrapup_global_declarations will (indirectly) call
+     rest_of_compilation again for those inline functions that need
+     to have out-of-line copies generated.  During that call, we
+     *will* be routed past here.  */
+
+  timevar_push (TV_SYMOUT);
+  (*debug_hooks->function_decl) (current_function_decl);
+  timevar_pop (TV_SYMOUT);
+  if (DECL_STATIC_CONSTRUCTOR (current_function_decl)
+      && targetm.have_ctors_dtors)
+    targetm.asm_out.constructor (XEXP (DECL_RTL (current_function_decl), 0),
+                                decl_init_priority_lookup
+                                  (current_function_decl));
+  if (DECL_STATIC_DESTRUCTOR (current_function_decl)
+      && targetm.have_ctors_dtors)
+    targetm.asm_out.destructor (XEXP (DECL_RTL (current_function_decl), 0),
+                               decl_fini_priority_lookup
+                                 (current_function_decl));
+  return 0;
+}
+
+struct rtl_opt_pass pass_final =
+{
+ {
+  RTL_PASS,
+  NULL,                                 /* name */
+  NULL,                                 /* gate */
+  rest_of_handle_final,                 /* execute */
+  NULL,                                 /* sub */
+  NULL,                                 /* next */
+  0,                                    /* static_pass_number */
+  TV_FINAL,                             /* tv_id */
+  0,                                    /* properties_required */
+  0,                                    /* properties_provided */
+  0,                                    /* properties_destroyed */
+  0,                                    /* todo_flags_start */
+  TODO_ggc_collect                      /* todo_flags_finish */
+ }
+};
+
+
+static unsigned int
+rest_of_handle_shorten_branches (void)
+{
+  /* Shorten branches.  */
+  shorten_branches (get_insns ());
+  return 0;
+}
+
+struct rtl_opt_pass pass_shorten_branches =
+{
+ {
+  RTL_PASS,
+  "shorten",                            /* name */
+  NULL,                                 /* gate */
+  rest_of_handle_shorten_branches,      /* execute */
+  NULL,                                 /* sub */
+  NULL,                                 /* next */
+  0,                                    /* static_pass_number */
+  TV_FINAL,                             /* tv_id */
+  0,                                    /* properties_required */
+  0,                                    /* properties_provided */
+  0,                                    /* properties_destroyed */
+  0,                                    /* todo_flags_start */
+  TODO_dump_func                        /* todo_flags_finish */
+ }
+};
+
+
+static unsigned int
+rest_of_clean_state (void)
+{
+  rtx insn, next;
+
+  /* It is very important to decompose the RTL instruction chain here:
+     debug information keeps pointing into CODE_LABEL insns inside the function
+     body.  If these remain pointing to the other insns, we end up preserving
+     whole RTL chain and attached detailed debug info in memory.  */
+  for (insn = get_insns (); insn; insn = next)
+    {
+      next = NEXT_INSN (insn);
+      NEXT_INSN (insn) = NULL;
+      PREV_INSN (insn) = NULL;
+    }
+
+  /* In case the function was not output,
+     don't leave any temporary anonymous types
+     queued up for sdb output.  */
+#ifdef SDB_DEBUGGING_INFO
+  if (write_symbols == SDB_DEBUG)
+    sdbout_types (NULL_TREE);
+#endif
+
+  reload_completed = 0;
+  epilogue_completed = 0;
+#ifdef STACK_REGS
+  regstack_completed = 0;
+#endif
+
+  /* Clear out the insn_length contents now that they are no
+     longer valid.  */
+  init_insn_lengths ();
+
+  /* Show no temporary slots allocated.  */
+  init_temp_slots ();
+
+  free_bb_for_insn ();
+
+  if (targetm.binds_local_p (current_function_decl))
+    {
+      unsigned int pref = crtl->preferred_stack_boundary;
+      if (crtl->stack_alignment_needed > crtl->preferred_stack_boundary)
+        pref = crtl->stack_alignment_needed;
+      cgraph_rtl_info (current_function_decl)->preferred_incoming_stack_boundary
+        = pref;
+    }
+
+  /* Make sure volatile mem refs aren't considered valid operands for
+     arithmetic insns.  We must call this here if this is a nested inline
+     function, since the above code leaves us in the init_recog state,
+     and the function context push/pop code does not save/restore volatile_ok.
+
+     ??? Maybe it isn't necessary for expand_start_function to call this
+     anymore if we do it here?  */
+
+  init_recog_no_volatile ();
+
+  /* We're done with this function.  Free up memory if we can.  */
+  free_after_parsing (cfun);
+  free_after_compilation (cfun);
+  return 0;
+}
+
+struct rtl_opt_pass pass_clean_state =
+{
+ {
+  RTL_PASS,
+  NULL,                                 /* name */
+  NULL,                                 /* gate */
+  rest_of_clean_state,                  /* execute */
+  NULL,                                 /* sub */
+  NULL,                                 /* next */
+  0,                                    /* static_pass_number */
+  TV_FINAL,                             /* tv_id */
+  0,                                    /* properties_required */
+  0,                                    /* properties_provided */
+  PROP_rtl,                             /* properties_destroyed */
+  0,                                    /* todo_flags_start */
+  0                                     /* todo_flags_finish */
+ }
+};
+