Index: gcc/read-md.h
===================================================================
--- gcc/read-md.h	2015-07-12 14:18:26.650113562 +0100
+++ gcc/read-md.h	2015-07-12 14:18:26.682112145 +0100
@@ -137,8 +137,6 @@ extern void fprint_c_condition (FILE *,
 extern void message_at (file_location, const char *, ...) ATTRIBUTE_PRINTF_2;
 extern void error_at (file_location, const char *, ...) ATTRIBUTE_PRINTF_2;
 extern void fatal_at (file_location, const char *, ...) ATTRIBUTE_PRINTF_2;
-extern void message_with_line (int, const char *, ...) ATTRIBUTE_PRINTF_2;
-extern void error_with_line (int, const char *, ...) ATTRIBUTE_PRINTF_2;
 extern void fatal_with_file_and_line (const char *, ...)
   ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
 extern void fatal_expected_char (int, int) ATTRIBUTE_NORETURN;
Index: gcc/read-md.c
===================================================================
--- gcc/read-md.c	2015-07-12 14:18:26.650113562 +0100
+++ gcc/read-md.c	2015-07-12 14:18:26.682112145 +0100
@@ -290,32 +290,6 @@ fatal_at (file_location loc, const char
   exit (1);
 }
 
-/* A printf-like function for reporting an error against line LINENO
-   in the current MD file.  */
-
-void
-message_with_line (int lineno, const char *msg, ...)
-{
-  va_list ap;
-
-  va_start (ap, msg);
-  message_at_1 (file_location (read_md_filename, lineno), msg, ap);
-  va_end (ap);
-}
-
-/* Like message_with_line, but treat the condition as an error.  */
-
-void
-error_with_line (int lineno, const char *msg, ...)
-{
-  va_list ap;
-
-  va_start (ap, msg);
-  message_at_1 (file_location (read_md_filename, lineno), msg, ap);
-  va_end (ap);
-  have_error = 1;
-}
-
 /* A printf-like function for reporting an error against the current
    position in the MD file.  */
 
Index: gcc/gensupport.h
===================================================================
--- gcc/gensupport.h	2015-07-12 14:18:26.668112765 +0100
+++ gcc/gensupport.h	2015-07-12 20:29:24.030447077 +0100
@@ -20,13 +20,29 @@ Software Foundation; either version 3, o
 #ifndef GCC_GENSUPPORT_H
 #define GCC_GENSUPPORT_H
 
+#include "read-md.h"
+
 struct obstack;
 extern struct obstack *rtl_obstack;
 
+/* Information about an .md define_* rtx.  */
+struct md_rtx_info {
+  /* The rtx itself.  */
+  rtx def;
+
+  /* The location of the first line of the rtx.  */
+  file_location loc;
+
+  /* The unique number attached to the rtx.  Currently all define_insns,
+     define_expands, define_splits, define_peepholes and define_peephole2s
+     share the same insn_code index space.  */
+  int index;
+};
+
 extern rtx add_implicit_parallel (rtvec);
 extern bool init_rtx_reader_args_cb (int, char **, bool (*)(const char *));
 extern bool init_rtx_reader_args (int, char **);
-extern rtx read_md_rtx (int *, int *);
+extern bool read_md_rtx (md_rtx_info *);
 
 /* Set this to 0 to disable automatic elision of insn patterns which
    can never be used in this configuration.  See genconditions.c.
Index: gcc/gensupport.c
===================================================================
--- gcc/gensupport.c	2015-07-12 14:18:26.668112765 +0100
+++ gcc/gensupport.c	2015-07-12 14:18:26.681112189 +0100
@@ -2529,14 +2529,11 @@ init_rtx_reader_args (int argc, char **a
   return init_rtx_reader_args_cb (argc, argv, 0);
 }
 
-/* The entry point for reading a single rtx from an md file.  Return
-   the rtx, or NULL if the md file has been fully processed.
-   Return the line where the rtx was found in LINENO.
-   Return the number of code generating rtx'en read since the start
-   of the md file in SEQNR.  */
+/* Try to read a single rtx from the file.  Return true on success,
+   describing it in *INFO.  */
 
-rtx
-read_md_rtx (int *lineno, int *seqnr)
+bool
+read_md_rtx (md_rtx_info *info)
 {
   struct queue_elem **queue, *elem;
   rtx desc;
@@ -2553,14 +2550,13 @@ read_md_rtx (int *lineno, int *seqnr)
   else if (other_queue != NULL)
     queue = &other_queue;
   else
-    return NULL_RTX;
+    return false;
 
   elem = *queue;
   *queue = elem->next;
-  desc = elem->data;
-  read_md_filename = elem->loc.filename;
-  *lineno = elem->loc.lineno;
-  *seqnr = sequence_num;
+  info->def = elem->data;
+  info->loc = elem->loc;
+  info->index = sequence_num;
 
   free (elem);
 
@@ -2570,6 +2566,7 @@ read_md_rtx (int *lineno, int *seqnr)
      elided patterns are never counted by the sequence numbering; it
      is the caller's responsibility, when insn_elision is false, not
      to use elided pattern numbers for anything.  */
+  desc = info->def;
   switch (GET_CODE (desc))
     {
     case DEFINE_INSN:
@@ -2580,9 +2577,9 @@ read_md_rtx (int *lineno, int *seqnr)
       else if (insn_elision)
 	goto discard;
 
-      /* *seqnr is used here so the name table will match caller's
+      /* info->index is used here so the name table will match caller's
 	 idea of insn numbering, whether or not elision is active.  */
-      record_insn_name (*seqnr, XSTR (desc, 0));
+      record_insn_name (info->index, XSTR (desc, 0));
       break;
 
     case DEFINE_SPLIT:
@@ -2591,14 +2588,14 @@ read_md_rtx (int *lineno, int *seqnr)
       if (maybe_eval_c_test (XSTR (desc, 1)) != 0)
 	sequence_num++;
       else if (insn_elision)
-	    goto discard;
+	goto discard;
       break;
 
     default:
       break;
     }
 
-  return desc;
+  return true;
 }
 
 /* Helper functions for insn elision.  */
Index: gcc/genattr-common.c
===================================================================
--- gcc/genattr-common.c	2015-07-12 14:18:07.691911409 +0100
+++ gcc/genattr-common.c	2015-07-12 14:18:26.676112411 +0100
@@ -37,10 +37,11 @@ write_upcase (const char *str)
 }
 
 static void
-gen_attr (rtx attr)
+gen_attr (md_rtx_info *info)
 {
   const char *p, *tag;
 
+  rtx attr = info->def;
   p = XSTR (attr, 1);
   if (*p != '\0')
     {
@@ -62,7 +63,6 @@ gen_attr (rtx attr)
 int
 main (int argc, char **argv)
 {
-  rtx desc;
   bool have_delay = false;
   bool have_sched = false;
 
@@ -78,34 +78,33 @@ main (int argc, char **argv)
 
   /* Read the machine description.  */
 
-  while (1)
-    {
-      int line_no, insn_code_number;
+  md_rtx_info info;
+  while (read_md_rtx (&info))
+    switch (GET_CODE (info.def))
+      {
+      case DEFINE_ATTR:
+	gen_attr (&info);
+	break;
 
-      desc = read_md_rtx (&line_no, &insn_code_number);
-      if (desc == NULL)
+      case DEFINE_DELAY:
+	if (!have_delay)
+	  {
+	    printf ("#define DELAY_SLOTS\n");
+	    have_delay = true;
+	  }
 	break;
 
-      if (GET_CODE (desc) == DEFINE_ATTR)
-	gen_attr (desc);
+      case DEFINE_INSN_RESERVATION:
+	if (!have_sched)
+	  {
+	    printf ("#define INSN_SCHEDULING\n");
+	    have_sched = true;
+	  }
+	break;
 
-      if (GET_CODE (desc) == DEFINE_DELAY)
-        {
-	  if (!have_delay)
-	    {
-	      printf ("#define DELAY_SLOTS\n");
-	      have_delay = true;
-	    }
-	}
-      else if (GET_CODE (desc) == DEFINE_INSN_RESERVATION)
-	{
-	  if (!have_sched)
-	    {
-	      printf ("#define INSN_SCHEDULING\n");
-	      have_sched = true;
-	    }
-	}
-    }
+      default:
+	break;
+      }
   puts ("\n#endif /* GCC_INSN_ATTR_COMMON_H */");
 
   if (ferror (stdout) || fflush (stdout) || fclose (stdout))
Index: gcc/genattr.c
===================================================================
--- gcc/genattr.c	2015-07-12 14:18:07.691911409 +0100
+++ gcc/genattr.c	2015-07-12 14:18:26.677112366 +0100
@@ -29,15 +29,14 @@ Software Foundation; either version 3, o
 #include "gensupport.h"
 
 
-static void gen_attr (rtx);
-
 static vec<rtx> const_attrs, reservations;
 
 
 static void
-gen_attr (rtx attr)
+gen_attr (md_rtx_info *info)
 {
   const char *p;
+  rtx attr = info->def;
   int is_const = GET_CODE (XEXP (attr, 2)) == CONST;
 
   if (is_const)
@@ -141,7 +140,6 @@ find_tune_attr (rtx exp)
 int
 main (int argc, char **argv)
 {
-  rtx desc;
   int have_delay = 0;
   int have_annul_true = 0;
   int have_annul_false = 0;
@@ -162,20 +160,18 @@ main (int argc, char **argv)
 
   /* Read the machine description.  */
 
-  while (1)
+  md_rtx_info info;
+  while (read_md_rtx (&info))
     {
-      int line_no, insn_code_number;
-
-      desc = read_md_rtx (&line_no, &insn_code_number);
-      if (desc == NULL)
-	break;
-
-      if (GET_CODE (desc) == DEFINE_ATTR
-	  || GET_CODE (desc) == DEFINE_ENUM_ATTR)
-	gen_attr (desc);
+      rtx def = info.def;
+      switch (GET_CODE (def))
+	{
+	case DEFINE_ATTR:
+	case DEFINE_ENUM_ATTR:
+	  gen_attr (&info);
+	  break;
 
-      else if (GET_CODE (desc) == DEFINE_DELAY)
-        {
+	case DEFINE_DELAY:
 	  if (! have_delay)
 	    {
 	      printf ("extern int num_delay_slots (rtx_insn *);\n");
@@ -184,28 +180,31 @@ main (int argc, char **argv)
 	      have_delay = 1;
 	    }
 
-	  for (i = 0; i < XVECLEN (desc, 1); i += 3)
+	  for (i = 0; i < XVECLEN (def, 1); i += 3)
 	    {
-	      if (XVECEXP (desc, 1, i + 1) && ! have_annul_true)
+	      if (XVECEXP (def, 1, i + 1) && ! have_annul_true)
 		{
 		  printf ("#define ANNUL_IFTRUE_SLOTS\n");
 		  printf ("extern int eligible_for_annul_true (rtx_insn *, int, rtx_insn *, int);\n");
 		  have_annul_true = 1;
 		}
 
-	      if (XVECEXP (desc, 1, i + 2) && ! have_annul_false)
+	      if (XVECEXP (def, 1, i + 2) && ! have_annul_false)
 		{
 		  printf ("#define ANNUL_IFFALSE_SLOTS\n");
 		  printf ("extern int eligible_for_annul_false (rtx_insn *, int, rtx_insn *, int);\n");
 		  have_annul_false = 1;
 		}
 	    }
-        }
+	  break;
 
-      else if (GET_CODE (desc) == DEFINE_INSN_RESERVATION)
-	{
+	case DEFINE_INSN_RESERVATION:
 	  num_insn_reservations++;
-	  reservations.safe_push (desc);
+	  reservations.safe_push (def);
+	  break;
+
+	default:
+	  break;
 	}
     }
 
Index: gcc/genattrtab.c
===================================================================
--- gcc/genattrtab.c	2015-07-12 14:18:26.650113562 +0100
+++ gcc/genattrtab.c	2015-07-12 20:41:32.084579584 +0100
@@ -211,7 +211,6 @@ struct attr_value_list **insn_code_value
 
 /* Other variables.  */
 
-static int insn_code_number;
 static int insn_index_number;
 static int got_define_asm_attributes;
 static int must_extract;
@@ -1016,7 +1015,7 @@ check_attr_value (rtx exp, struct attr_d
 	struct attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
 	if (attr2 == NULL)
 	  error_at (attr->loc, "unknown attribute `%s' in ATTR",
-			   XSTR (exp, 0));
+		    XSTR (exp, 0));
 	else if (attr->is_const && ! attr2->is_const)
 	  error_at (attr->loc,
 		    "non-constant attribute `%s' referenced from `%s'",
@@ -2950,10 +2949,11 @@ get_attr_order (struct attr_desc ***ret)
 
 /* Optimize the attribute lists by seeing if we can determine conditional
    values from the known values of other attributes.  This will save subroutine
-   calls during the compilation.  */
+   calls during the compilation.  MAX_INSN_CODE is the number of unique
+   instruction codes.  */
 
 static void
-optimize_attrs (void)
+optimize_attrs (int max_insn_code)
 {
   struct attr_desc *attr;
   struct attr_value *av;
@@ -2972,7 +2972,7 @@ optimize_attrs (void)
     return;
 
   /* Make 2 extra elements, for "code" values -2 and -1.  */
-  insn_code_values = XCNEWVEC (struct attr_value_list *, insn_code_number + 2);
+  insn_code_values = XCNEWVEC (struct attr_value_list *, max_insn_code + 2);
 
   /* Offset the table address so we can index by -2 or -1.  */
   insn_code_values += 2;
@@ -3000,7 +3000,7 @@ optimize_attrs (void)
   gcc_assert (iv == ivbuf + num_insn_ents);
 
   /* Process one insn code at a time.  */
-  for (i = -2; i < insn_code_number; i++)
+  for (i = -2; i < max_insn_code; i++)
     {
       /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
 	 We use it to mean "already simplified for this insn".  */
@@ -3126,63 +3126,64 @@ add_attr_value (struct attr_desc *attr,
 /* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR.  */
 
 static void
-gen_attr (rtx exp, int lineno)
+gen_attr (md_rtx_info *info)
 {
   struct enum_type *et;
   struct enum_value *ev;
   struct attr_desc *attr;
   const char *name_ptr;
   char *p;
+  rtx def = info->def;
 
   /* Make a new attribute structure.  Check for duplicate by looking at
      attr->default_val, since it is initialized by this routine.  */
-  attr = find_attr (&XSTR (exp, 0), 1);
+  attr = find_attr (&XSTR (def, 0), 1);
   if (attr->default_val)
     {
-      error_with_line (lineno, "duplicate definition for attribute %s",
-		       attr->name);
+      error_at (info->loc, "duplicate definition for attribute %s",
+		attr->name);
       message_at (attr->loc, "previous definition");
       return;
     }
-  attr->loc = file_location (read_md_filename, lineno);
+  attr->loc = info->loc;
 
-  if (GET_CODE (exp) == DEFINE_ENUM_ATTR)
+  if (GET_CODE (def) == DEFINE_ENUM_ATTR)
     {
-      attr->enum_name = XSTR (exp, 1);
-      et = lookup_enum_type (XSTR (exp, 1));
+      attr->enum_name = XSTR (def, 1);
+      et = lookup_enum_type (XSTR (def, 1));
       if (!et || !et->md_p)
-	error_with_line (lineno, "No define_enum called `%s' defined",
-			 attr->name);
+	error_at (info->loc, "No define_enum called `%s' defined",
+		  attr->name);
       if (et)
 	for (ev = et->values; ev; ev = ev->next)
 	  add_attr_value (attr, ev->name);
     }
-  else if (*XSTR (exp, 1) == '\0')
+  else if (*XSTR (def, 1) == '\0')
     attr->is_numeric = 1;
   else
     {
-      name_ptr = XSTR (exp, 1);
+      name_ptr = XSTR (def, 1);
       while ((p = next_comma_elt (&name_ptr)) != NULL)
 	add_attr_value (attr, p);
     }
 
-  if (GET_CODE (XEXP (exp, 2)) == CONST)
+  if (GET_CODE (XEXP (def, 2)) == CONST)
     {
       attr->is_const = 1;
       if (attr->is_numeric)
-	error_with_line (lineno,
-			 "constant attributes may not take numeric values");
+	error_at (info->loc,
+		  "constant attributes may not take numeric values");
 
       /* Get rid of the CONST node.  It is allowed only at top-level.  */
-      XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
+      XEXP (def, 2) = XEXP (XEXP (def, 2), 0);
     }
 
   if (! strcmp_check (attr->name, length_str) && ! attr->is_numeric)
-    error_with_line (lineno, "`length' attribute must take numeric values");
+    error_at (info->loc, "`length' attribute must take numeric values");
 
   /* Set up the default value.  */
-  XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
-  attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
+  XEXP (def, 2) = check_attr_value (XEXP (def, 2), attr);
+  attr->default_val = get_attr_value (XEXP (def, 2), attr, -2);
 }
 
 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
@@ -3258,31 +3259,32 @@ compares_alternatives_p (rtx exp)
 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES.  */
 
 static void
-gen_insn (rtx exp, int lineno)
+gen_insn (md_rtx_info *info)
 {
   struct insn_def *id;
+  rtx def = info->def;
 
   id = oballoc (struct insn_def);
   id->next = defs;
   defs = id;
-  id->def = exp;
-  id->loc = file_location (read_md_filename, lineno);
+  id->def = def;
+  id->loc = info->loc;
 
-  switch (GET_CODE (exp))
+  switch (GET_CODE (def))
     {
     case DEFINE_INSN:
-      id->insn_code = insn_code_number;
+      id->insn_code = info->index;
       id->insn_index = insn_index_number;
-      id->num_alternatives = count_alternatives (exp);
+      id->num_alternatives = count_alternatives (def);
       if (id->num_alternatives == 0)
 	id->num_alternatives = 1;
       id->vec_idx = 4;
       break;
 
     case DEFINE_PEEPHOLE:
-      id->insn_code = insn_code_number;
+      id->insn_code = info->index;
       id->insn_index = insn_index_number;
-      id->num_alternatives = count_alternatives (exp);
+      id->num_alternatives = count_alternatives (def);
       if (id->num_alternatives == 0)
 	id->num_alternatives = 1;
       id->vec_idx = 3;
@@ -3305,16 +3307,16 @@ gen_insn (rtx exp, int lineno)
    true or annul false is specified, and make a `struct delay_desc'.  */
 
 static void
-gen_delay (rtx def, int lineno)
+gen_delay (md_rtx_info *info)
 {
   struct delay_desc *delay;
   int i;
 
+  rtx def = info->def;
   if (XVECLEN (def, 1) % 3 != 0)
     {
-      error_with_line (lineno,
-		       "number of elements in DEFINE_DELAY must"
-		       " be multiple of three");
+      error_at (info->loc, "number of elements in DEFINE_DELAY must"
+		" be multiple of three");
       return;
     }
 
@@ -3330,7 +3332,7 @@ gen_delay (rtx def, int lineno)
   delay->def = def;
   delay->num = ++num_delays;
   delay->next = delays;
-  delay->loc = file_location (read_md_filename, lineno);
+  delay->loc = info->loc;
   delays = delay;
 }
 
@@ -4723,14 +4725,14 @@ static struct insn_reserv **last_insn_re
 /* Store information from a DEFINE_INSN_RESERVATION for future
    attribute generation.  */
 static void
-gen_insn_reserv (rtx def, int lineno)
+gen_insn_reserv (md_rtx_info *info)
 {
   struct insn_reserv *decl = oballoc (struct insn_reserv);
-  file_location loc (read_md_filename, lineno);
+  rtx def = info->def;
 
   decl->name            = DEF_ATTR_STRING (XSTR (def, 0));
   decl->default_latency = XINT (def, 1);
-  decl->condexp         = check_attr_test (XEXP (def, 2), 0, loc);
+  decl->condexp         = check_attr_test (XEXP (def, 2), 0, info->loc);
   decl->insn_num        = n_insn_reservs;
   decl->bypassed	= false;
   decl->next            = 0;
@@ -4776,10 +4778,11 @@ gen_bypass_1 (const char *s, size_t len)
 }
 
 static void
-gen_bypass (rtx def)
+gen_bypass (md_rtx_info *info)
 {
   const char *p, *base;
 
+  rtx def = info->def;
   for (p = base = XSTR (def, 1); *p; p++)
     if (*p == ',')
       {
@@ -5150,11 +5153,10 @@ handle_arg (const char *arg)
 int
 main (int argc, char **argv)
 {
-  rtx desc;
   struct attr_desc *attr;
   struct insn_def *id;
-  rtx tem;
   int i;
+  int max_insn_code = 0;
 
   progname = "genattrtab";
 
@@ -5184,57 +5186,56 @@ main (int argc, char **argv)
 
   /* Read the machine description.  */
 
-  while (1)
+  md_rtx_info info;
+  while (read_md_rtx (&info))
     {
-      int lineno;
-
-      desc = read_md_rtx (&lineno, &insn_code_number);
-      if (desc == NULL)
-	break;
-
-      switch (GET_CODE (desc))
+      switch (GET_CODE (info.def))
 	{
 	case DEFINE_INSN:
 	case DEFINE_PEEPHOLE:
 	case DEFINE_ASM_ATTRIBUTES:
-	  gen_insn (desc, lineno);
+	  gen_insn (&info);
 	  break;
 
 	case DEFINE_ATTR:
 	case DEFINE_ENUM_ATTR:
-	  gen_attr (desc, lineno);
+	  gen_attr (&info);
 	  break;
 
 	case DEFINE_DELAY:
-	  gen_delay (desc, lineno);
+	  gen_delay (&info);
 	  break;
 
 	case DEFINE_INSN_RESERVATION:
-	  gen_insn_reserv (desc, lineno);
+	  gen_insn_reserv (&info);
 	  break;
 
 	case DEFINE_BYPASS:
-	  gen_bypass (desc);
+	  gen_bypass (&info);
 	  break;
 
 	default:
 	  break;
 	}
-      if (GET_CODE (desc) != DEFINE_ASM_ATTRIBUTES)
+      if (GET_CODE (info.def) != DEFINE_ASM_ATTRIBUTES)
 	insn_index_number++;
+      max_insn_code = info.index;
     }
 
   if (have_error)
     return FATAL_EXIT_CODE;
 
-  insn_code_number++;
+  max_insn_code++;
 
   /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one.  */
   if (! got_define_asm_attributes)
     {
-      tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
-      XVEC (tem, 0) = rtvec_alloc (0);
-      gen_insn (tem, 0);
+      md_rtx_info info;
+      info.def = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
+      XVEC (info.def, 0) = rtvec_alloc (0);
+      info.loc = file_location ("<internal>", 0);
+      info.index = -1;
+      gen_insn (&info);
     }
 
   /* Expand DEFINE_DELAY information into new attribute.  */
@@ -5242,14 +5243,14 @@ main (int argc, char **argv)
     expand_delays ();
 
   /* Make `insn_alternatives'.  */
-  insn_alternatives = oballocvec (uint64_t, insn_code_number);
+  insn_alternatives = oballocvec (uint64_t, max_insn_code);
   for (id = defs; id; id = id->next)
     if (id->insn_code >= 0)
       insn_alternatives[id->insn_code]
 	= (((uint64_t) 1) << id->num_alternatives) - 1;
 
   /* Make `insn_n_alternatives'.  */
-  insn_n_alternatives = oballocvec (int, insn_code_number);
+  insn_n_alternatives = oballocvec (int, max_insn_code);
   for (id = defs; id; id = id->next)
     if (id->insn_code >= 0)
       insn_n_alternatives[id->insn_code] = id->num_alternatives;
@@ -5278,7 +5279,7 @@ main (int argc, char **argv)
   make_length_attrs ();
 
   /* Perform any possible optimizations to speed up compilation.  */
-  optimize_attrs ();
+  optimize_attrs (max_insn_code);
 
   /* Now write out all the `gen_attr_...' routines.  Do these before the
      special routines so that they get defined before they are used.  */
Index: gcc/genautomata.c
===================================================================
--- gcc/genautomata.c	2015-07-12 14:18:21.153357004 +0100
+++ gcc/genautomata.c	2015-07-12 20:41:11.300433721 +0100
@@ -1243,16 +1243,18 @@ get_str_vect (const char *str, int *els_
    This gives information about a unit contained in CPU.  We fill a
    struct unit_decl with information used later by `expand_automata'.  */
 static void
-gen_cpu_unit (rtx def)
+gen_cpu_unit (md_rtx_info *info)
 {
   decl_t decl;
   char **str_cpu_units;
   int vect_length;
   int i;
 
+  rtx def = info->def;
   str_cpu_units = get_str_vect (XSTR (def, 0), &vect_length, ',', FALSE);
   if (str_cpu_units == NULL)
-    fatal ("invalid string `%s' in define_cpu_unit", XSTR (def, 0));
+    fatal_at (info->loc, "invalid string `%s' in %s",
+	      XSTR (def, 0), GET_RTX_NAME (GET_CODE (def)));
   for (i = 0; i < vect_length; i++)
     {
       decl = XCREATENODE (struct decl);
@@ -1272,17 +1274,19 @@ gen_cpu_unit (rtx def)
    This gives information about a unit contained in CPU.  We fill a
    struct unit_decl with information used later by `expand_automata'.  */
 static void
-gen_query_cpu_unit (rtx def)
+gen_query_cpu_unit (md_rtx_info *info)
 {
   decl_t decl;
   char **str_cpu_units;
   int vect_length;
   int i;
 
+  rtx def = info->def;
   str_cpu_units = get_str_vect (XSTR (def, 0), &vect_length, ',',
 				FALSE);
   if (str_cpu_units == NULL)
-    fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def, 0));
+    fatal_at (info->loc, "invalid string `%s' in %s",
+	      XSTR (def, 0), GET_RTX_NAME (GET_CODE (def)));
   for (i = 0; i < vect_length; i++)
     {
       decl = XCREATENODE (struct decl);
@@ -1301,7 +1305,7 @@ gen_query_cpu_unit (rtx def)
    in a struct bypass_decl with information used later by
    `expand_automata'.  */
 static void
-gen_bypass (rtx def)
+gen_bypass (md_rtx_info *info)
 {
   decl_t decl;
   char **out_patterns;
@@ -1310,12 +1314,15 @@ gen_bypass (rtx def)
   int in_length;
   int i, j;
 
+  rtx def = info->def;
   out_patterns = get_str_vect (XSTR (def, 1), &out_length, ',', FALSE);
   if (out_patterns == NULL)
-    fatal ("invalid string `%s' in define_bypass", XSTR (def, 1));
+    fatal_at (info->loc, "invalid string `%s' in %s",
+	      XSTR (def, 1), GET_RTX_NAME (GET_CODE (def)));
   in_patterns = get_str_vect (XSTR (def, 2), &in_length, ',', FALSE);
   if (in_patterns == NULL)
-    fatal ("invalid string `%s' in define_bypass", XSTR (def, 2));
+    fatal_at (info->loc, "invalid string `%s' in %s",
+	      XSTR (def, 2), GET_RTX_NAME (GET_CODE (def)));
   for (i = 0; i < out_length; i++)
     for (j = 0; j < in_length; j++)
       {
@@ -1336,7 +1343,7 @@ gen_bypass (rtx def)
    struct excl_rel_decl (excl) with information used later by
    `expand_automata'.  */
 static void
-gen_excl_set (rtx def)
+gen_excl_set (md_rtx_info *info)
 {
   decl_t decl;
   char **first_str_cpu_units;
@@ -1345,16 +1352,20 @@ gen_excl_set (rtx def)
   int length;
   int i;
 
+  rtx def = info->def;
   first_str_cpu_units
     = get_str_vect (XSTR (def, 0), &first_vect_length, ',', FALSE);
   if (first_str_cpu_units == NULL)
-    fatal ("invalid first string `%s' in exclusion_set", XSTR (def, 0));
+    fatal_at (info->loc, "invalid string `%s' in %s",
+	      XSTR (def, 0), GET_RTX_NAME (GET_CODE (def)));
   second_str_cpu_units = get_str_vect (XSTR (def, 1), &length, ',',
 				       FALSE);
   if (second_str_cpu_units == NULL)
-    fatal ("invalid second string `%s' in exclusion_set", XSTR (def, 1));
+    fatal_at (info->loc, "invalid string `%s' in %s",
+	      XSTR (def, 1), GET_RTX_NAME (GET_CODE (def)));
   length += first_vect_length;
-  decl = XCREATENODEVAR (struct decl, sizeof (struct decl) + (length - 1) * sizeof (char *));
+  decl = XCREATENODEVAR (struct decl, (sizeof (struct decl)
+				       + (length - 1) * sizeof (char *)));
   decl->mode = dm_excl;
   decl->pos = 0;
   DECL_EXCL (decl)->all_names_num = length;
@@ -1375,7 +1386,7 @@ gen_excl_set (rtx def)
    We fill a struct unit_pattern_rel_decl with information used later
    by `expand_automata'.  */
 static void
-gen_presence_absence_set (rtx def, int presence_p, int final_p)
+gen_presence_absence_set (md_rtx_info *info, int presence_p, int final_p)
 {
   decl_t decl;
   char **str_cpu_units;
@@ -1386,27 +1397,17 @@ gen_presence_absence_set (rtx def, int p
   int patterns_length;
   int i;
 
+  rtx def = info->def;
   str_cpu_units = get_str_vect (XSTR (def, 0), &cpu_units_length, ',',
 				FALSE);
   if (str_cpu_units == NULL)
-    fatal ((presence_p
-	    ? (final_p
-	       ? "invalid first string `%s' in final_presence_set"
-	       : "invalid first string `%s' in presence_set")
-	    : (final_p
-	       ? "invalid first string `%s' in final_absence_set"
-	       : "invalid first string `%s' in absence_set")),
-	   XSTR (def, 0));
+    fatal_at (info->loc, "invalid string `%s' in %s",
+	      XSTR (def, 0), GET_RTX_NAME (GET_CODE (def)));
   str_pattern_lists = get_str_vect (XSTR (def, 1),
 				    &patterns_length, ',', FALSE);
   if (str_pattern_lists == NULL)
-    fatal ((presence_p
-	    ? (final_p
-	       ? "invalid second string `%s' in final_presence_set"
-	       : "invalid second string `%s' in presence_set")
-	    : (final_p
-	       ? "invalid second string `%s' in final_absence_set"
-	       : "invalid second string `%s' in absence_set")), XSTR (def, 1));
+    fatal_at (info->loc, "invalid string `%s' in %s",
+	      XSTR (def, 1), GET_RTX_NAME (GET_CODE (def)));
   str_patterns = XOBNEWVEC (&irp, char **, patterns_length);
   for (i = 0; i < patterns_length; i++)
     {
@@ -1439,13 +1440,13 @@ gen_presence_absence_set (rtx def, int p
 
 /* Process a PRESENCE_SET.
 
-    This gives information about a cpu unit reservation requirements.
+   This gives information about a cpu unit reservation requirements.
    We fill a struct unit_pattern_rel_decl (presence) with information
    used later by `expand_automata'.  */
 static void
-gen_presence_set (rtx def)
+gen_presence_set (md_rtx_info *info)
 {
-  gen_presence_absence_set (def, TRUE, FALSE);
+  gen_presence_absence_set (info, TRUE, FALSE);
 }
 
 /* Process a FINAL_PRESENCE_SET.
@@ -1454,9 +1455,9 @@ gen_presence_set (rtx def)
    We fill a struct unit_pattern_rel_decl (presence) with information
    used later by `expand_automata'.  */
 static void
-gen_final_presence_set (rtx def)
+gen_final_presence_set (md_rtx_info *info)
 {
-  gen_presence_absence_set (def, TRUE, TRUE);
+  gen_presence_absence_set (info, TRUE, TRUE);
 }
 
 /* Process an ABSENCE_SET.
@@ -1465,9 +1466,9 @@ gen_final_presence_set (rtx def)
    We fill a struct unit_pattern_rel_decl (absence) with information
    used later by `expand_automata'.  */
 static void
-gen_absence_set (rtx def)
+gen_absence_set (md_rtx_info *info)
 {
-  gen_presence_absence_set (def, FALSE, FALSE);
+  gen_presence_absence_set (info, FALSE, FALSE);
 }
 
 /* Process a FINAL_ABSENCE_SET.
@@ -1476,9 +1477,9 @@ gen_absence_set (rtx def)
    We fill a struct unit_pattern_rel_decl (absence) with information
    used later by `expand_automata'.  */
 static void
-gen_final_absence_set (rtx def)
+gen_final_absence_set (md_rtx_info *info)
 {
-  gen_presence_absence_set (def, FALSE, TRUE);
+  gen_presence_absence_set (info, FALSE, TRUE);
 }
 
 /* Process a DEFINE_AUTOMATON.
@@ -1487,16 +1488,18 @@ gen_final_absence_set (rtx def)
    recognizing pipeline hazards.  We fill a struct automaton_decl
    with information used later by `expand_automata'.  */
 static void
-gen_automaton (rtx def)
+gen_automaton (md_rtx_info *info)
 {
   decl_t decl;
   char **str_automata;
   int vect_length;
   int i;
 
+  rtx def = info->def;
   str_automata = get_str_vect (XSTR (def, 0), &vect_length, ',', FALSE);
   if (str_automata == NULL)
-    fatal ("invalid string `%s' in define_automaton", XSTR (def, 0));
+    fatal_at (info->loc, "invalid string `%s' in %s",
+	      XSTR (def, 0), GET_RTX_NAME (GET_CODE (def)));
   for (i = 0; i < vect_length; i++)
     {
       decl = XCREATENODE (struct decl);
@@ -1512,28 +1515,30 @@ gen_automaton (rtx def)
    This gives information how to generate finite state automaton used
    for recognizing pipeline hazards.  */
 static void
-gen_automata_option (rtx def)
+gen_automata_option (md_rtx_info *info)
 {
-  if (strcmp (XSTR (def, 0), NO_MINIMIZATION_OPTION + 1) == 0)
+  const char *option = XSTR (info->def, 0);
+  if (strcmp (option, NO_MINIMIZATION_OPTION + 1) == 0)
     no_minimization_flag = 1;
-  else if (strcmp (XSTR (def, 0), TIME_OPTION + 1) == 0)
+  else if (strcmp (option, TIME_OPTION + 1) == 0)
     time_flag = 1;
-  else if (strcmp (XSTR (def, 0), STATS_OPTION + 1) == 0)
+  else if (strcmp (option, STATS_OPTION + 1) == 0)
     stats_flag = 1;
-  else if (strcmp (XSTR (def, 0), V_OPTION + 1) == 0)
+  else if (strcmp (option, V_OPTION + 1) == 0)
     v_flag = 1;
-  else if (strcmp (XSTR (def, 0), W_OPTION + 1) == 0)
+  else if (strcmp (option, W_OPTION + 1) == 0)
     w_flag = 1;
-  else if (strcmp (XSTR (def, 0), NDFA_OPTION + 1) == 0)
+  else if (strcmp (option, NDFA_OPTION + 1) == 0)
     ndfa_flag = 1;
-  else if (strcmp (XSTR (def, 0), COLLAPSE_OPTION + 1) == 0)
+  else if (strcmp (option, COLLAPSE_OPTION + 1) == 0)
     collapse_flag = 1;
-  else if (strcmp (XSTR (def, 0), NO_COMB_OPTION + 1) == 0)
+  else if (strcmp (option, NO_COMB_OPTION + 1) == 0)
     no_comb_flag = 1;
-  else if (strcmp (XSTR (def, 0), PROGRESS_OPTION + 1) == 0)
+  else if (strcmp (option, PROGRESS_OPTION + 1) == 0)
     progress_flag = 1;
   else
-    fatal ("invalid option `%s' in automata_option", XSTR (def, 0));
+    fatal_at (info->loc, "invalid option `%s' in %s",
+	      option, GET_RTX_NAME (GET_CODE (info->def)));
 }
 
 /* Name in reservation to denote absence reservation.  */
@@ -1703,10 +1708,11 @@ gen_regexp (const char *str)
    in a struct reserv_decl with information used later by
    `expand_automata'.  */
 static void
-gen_reserv (rtx def)
+gen_reserv (md_rtx_info *info)
 {
   decl_t decl;
 
+  rtx def = info->def;
   decl = XCREATENODE (struct decl);
   decl->mode = dm_reserv;
   decl->pos = 0;
@@ -1721,10 +1727,11 @@ gen_reserv (rtx def)
    insn.  We fill a struct insn_reserv_decl with information used
    later by `expand_automata'.  */
 static void
-gen_insn_reserv (rtx def)
+gen_insn_reserv (md_rtx_info *info)
 {
   decl_t decl;
 
+  rtx def = info->def;
   decl = XCREATENODE (struct decl);
   decl->mode = dm_insn_reserv;
   decl->pos = 0;
@@ -9587,77 +9594,67 @@ write_automata (void)
 int
 main (int argc, char **argv)
 {
-  rtx desc;
-
   progname = "genautomata";
 
   if (!init_rtx_reader_args_cb (argc, argv, parse_automata_opt))
     return (FATAL_EXIT_CODE);
 
   initiate_automaton_gen (argv);
-  while (1)
-    {
-      int lineno;
-      int insn_code_number;
-
-      desc = read_md_rtx (&lineno, &insn_code_number);
-      if (desc == NULL)
+  md_rtx_info info;
+  while (read_md_rtx (&info))
+    switch (GET_CODE (info.def))
+      {
+      case DEFINE_CPU_UNIT:
+	gen_cpu_unit (&info);
 	break;
 
-      switch (GET_CODE (desc))
-	{
-	case DEFINE_CPU_UNIT:
-	  gen_cpu_unit (desc);
-	  break;
-
-	case DEFINE_QUERY_CPU_UNIT:
-	  gen_query_cpu_unit (desc);
-	  break;
+      case DEFINE_QUERY_CPU_UNIT:
+	gen_query_cpu_unit (&info);
+	break;
 
-	case DEFINE_BYPASS:
-	  gen_bypass (desc);
-	  break;
+      case DEFINE_BYPASS:
+	gen_bypass (&info);
+	break;
 
-	case EXCLUSION_SET:
-	  gen_excl_set (desc);
-	  break;
+      case EXCLUSION_SET:
+	gen_excl_set (&info);
+	break;
 
-	case PRESENCE_SET:
-	  gen_presence_set (desc);
-	  break;
+      case PRESENCE_SET:
+	gen_presence_set (&info);
+	break;
 
-	case FINAL_PRESENCE_SET:
-	  gen_final_presence_set (desc);
-	  break;
+      case FINAL_PRESENCE_SET:
+	gen_final_presence_set (&info);
+	break;
 
-	case ABSENCE_SET:
-	  gen_absence_set (desc);
-	  break;
+      case ABSENCE_SET:
+	gen_absence_set (&info);
+	break;
 
-	case FINAL_ABSENCE_SET:
-	  gen_final_absence_set (desc);
-	  break;
+      case FINAL_ABSENCE_SET:
+	gen_final_absence_set (&info);
+	break;
 
-	case DEFINE_AUTOMATON:
-	  gen_automaton (desc);
-	  break;
+      case DEFINE_AUTOMATON:
+	gen_automaton (&info);
+	break;
 
-	case AUTOMATA_OPTION:
-	  gen_automata_option (desc);
-	  break;
+      case AUTOMATA_OPTION:
+	gen_automata_option (&info);
+	break;
 
-	case DEFINE_RESERVATION:
-	  gen_reserv (desc);
-	  break;
+      case DEFINE_RESERVATION:
+	gen_reserv (&info);
+	break;
 
-	case DEFINE_INSN_RESERVATION:
-	  gen_insn_reserv (desc);
-	  break;
+      case DEFINE_INSN_RESERVATION:
+	gen_insn_reserv (&info);
+	break;
 
-	default:
-	  break;
-	}
-    }
+      default:
+	break;
+      }
 
   if (have_error)
     return FATAL_EXIT_CODE;
Index: gcc/gencodes.c
===================================================================
--- gcc/gencodes.c	2015-07-12 14:18:07.691911409 +0100
+++ gcc/gencodes.c	2015-07-12 14:18:26.678112322 +0100
@@ -29,10 +29,10 @@ Software Foundation; either version 3, o
 #include "gensupport.h"
 
 static void
-gen_insn (rtx insn, int code)
+gen_insn (md_rtx_info *info)
 {
-  const char *name = XSTR (insn, 0);
-  int truth = maybe_eval_c_test (XSTR (insn, 2));
+  const char *name = XSTR (info->def, 0);
+  int truth = maybe_eval_c_test (XSTR (info->def, 2));
 
   /* Don't mention instructions whose names are the null string
      or begin with '*'.  They are in the machine description just
@@ -42,14 +42,13 @@ gen_insn (rtx insn, int code)
       if (truth == 0)
 	printf ("#define CODE_FOR_%s CODE_FOR_nothing\n", name);
       else
-	printf ("  CODE_FOR_%s = %d,\n", name, code);
+	printf ("  CODE_FOR_%s = %d,\n", name, info->index);
     }
 }
 
 int
 main (int argc, char **argv)
 {
-  rtx desc;
   int last = 1;
 
   progname = "gencodes";
@@ -73,20 +72,18 @@ enum insn_code {\n\
 
   /* Read the machine description.  */
 
-  while (1)
-    {
-      int line_no;
-      int insn_code_number;
-
-      desc = read_md_rtx (&line_no, &insn_code_number);
-      if (desc == NULL)
+  md_rtx_info info;
+  while (read_md_rtx (&info))
+    switch (GET_CODE (info.def))
+      {
+      case DEFINE_INSN:
+      case DEFINE_EXPAND:
+	gen_insn (&info);
+	last = info.index + 1;
 	break;
 
-      if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
-	{
-	  gen_insn (desc, insn_code_number);
-	  last = insn_code_number + 1;
-	}
+      default:
+	break;
     }
 
   printf ("  LAST_INSN_CODE = %d\n\
Index: gcc/genconditions.c
===================================================================
--- gcc/genconditions.c	2015-07-12 14:18:22.160312408 +0100
+++ gcc/genconditions.c	2015-07-12 14:18:26.678112322 +0100
@@ -212,42 +212,36 @@ write_writer (void)
 int
 main (int argc, char **argv)
 {
-  rtx desc;
-  int pattern_lineno; /* not used */
-  int code;
-
   progname = "genconditions";
 
   if (!init_rtx_reader_args (argc, argv))
     return (FATAL_EXIT_CODE);
 
   /* Read the machine description.  */
-  while (1)
+  md_rtx_info info;
+  while (read_md_rtx (&info))
     {
-      desc = read_md_rtx (&pattern_lineno, &code);
-      if (desc == NULL)
-	break;
-
+      rtx def = info.def;
       /* N.B. define_insn_and_split, define_cond_exec are handled
 	 entirely within read_md_rtx; we never see them.  */
-      switch (GET_CODE (desc))
+      switch (GET_CODE (def))
 	{
-	default:
-	  break;
-
 	case DEFINE_INSN:
 	case DEFINE_EXPAND:
-	  add_c_test (XSTR (desc, 2), -1);
+	  add_c_test (XSTR (def, 2), -1);
 	  /* except.h needs to know whether there is an eh_return
 	     pattern in the machine description.  */
-	  if (!strcmp (XSTR (desc, 0), "eh_return"))
+	  if (!strcmp (XSTR (def, 0), "eh_return"))
 	    saw_eh_return = 1;
 	  break;
 
 	case DEFINE_SPLIT:
 	case DEFINE_PEEPHOLE:
 	case DEFINE_PEEPHOLE2:
-	  add_c_test (XSTR (desc, 1), -1);
+	  add_c_test (XSTR (def, 1), -1);
+	  break;
+
+	default:
 	  break;
 	}
     }
Index: gcc/genconfig.c
===================================================================
--- gcc/genconfig.c	2015-07-12 14:18:07.691911409 +0100
+++ gcc/genconfig.c	2015-07-12 14:18:26.679112278 +0100
@@ -51,11 +51,6 @@ static int max_insns_per_split = 1;
 static int dup_operands_seen_this_insn;
 
 static void walk_insn_part (rtx, int, int);
-static void gen_insn (rtx);
-static void gen_expand (rtx);
-static void gen_split (rtx);
-static void gen_peephole (rtx);
-static void gen_peephole2 (rtx);
 
 /* RECOG_P will be nonzero if this pattern was seen in a context where it will
    be used to recognize, rather than just generate an insn.
@@ -179,11 +174,12 @@ walk_insn_part (rtx part, int recog_p, i
 }
 
 static void
-gen_insn (rtx insn)
+gen_insn (md_rtx_info *info)
 {
   int i;
 
   /* Walk the insn pattern to gather the #define's status.  */
+  rtx insn = info->def;
   clobbers_seen_this_insn = 0;
   dup_operands_seen_this_insn = 0;
   if (XVEC (insn, 1) != 0)
@@ -199,7 +195,7 @@ gen_insn (rtx insn)
 /* Similar but scan a define_expand.  */
 
 static void
-gen_expand (rtx insn)
+gen_expand (md_rtx_info *info)
 {
   int i;
 
@@ -207,6 +203,7 @@ gen_expand (rtx insn)
 
   /* Note that we don't bother recording the number of MATCH_DUPs
      that occur in a gen_expand, because only reload cares about that.  */
+  rtx insn = info->def;
   if (XVEC (insn, 1) != 0)
     for (i = 0; i < XVECLEN (insn, 1); i++)
       {
@@ -225,12 +222,13 @@ gen_expand (rtx insn)
 /* Similar but scan a define_split.  */
 
 static void
-gen_split (rtx split)
+gen_split (md_rtx_info *info)
 {
   int i;
 
   /* Look through the patterns that are matched
      to compute the maximum operand number.  */
+  rtx split = info->def;
   for (i = 0; i < XVECLEN (split, 0); i++)
     walk_insn_part (XVECEXP (split, 0, i), 1, 0);
   /* Look at the number of insns this insn could split into.  */
@@ -239,23 +237,25 @@ gen_split (rtx split)
 }
 
 static void
-gen_peephole (rtx peep)
+gen_peephole (md_rtx_info *info)
 {
   int i;
 
   /* Look through the patterns that are matched
      to compute the maximum operand number.  */
+  rtx peep = info->def;
   for (i = 0; i < XVECLEN (peep, 0); i++)
     walk_insn_part (XVECEXP (peep, 0, i), 1, 0);
 }
 
 static void
-gen_peephole2 (rtx peep)
+gen_peephole2 (md_rtx_info *info)
 {
   int i, n;
 
   /* Look through the patterns that are matched
      to compute the maximum operand number.  */
+  rtx peep = info->def;
   for (i = XVECLEN (peep, 0) - 1; i >= 0; --i)
     walk_insn_part (XVECEXP (peep, 0, i), 1, 0);
 
@@ -271,8 +271,6 @@ gen_peephole2 (rtx peep)
 int
 main (int argc, char **argv)
 {
-  rtx desc;
-
   progname = "genconfig";
 
   if (!init_rtx_reader_args (argc, argv))
@@ -291,42 +289,35 @@ main (int argc, char **argv)
 
   /* Read the machine description.  */
 
-  while (1)
-    {
-      int line_no, insn_code_number = 0;
+  md_rtx_info info;
+  while (read_md_rtx (&info))
+    switch (GET_CODE (info.def))
+      {
+      case DEFINE_INSN:
+	gen_insn (&info);
+	break;
 
-      desc = read_md_rtx (&line_no, &insn_code_number);
-      if (desc == NULL)
+      case DEFINE_EXPAND:
+	gen_expand (&info);
 	break;
 
-      switch (GET_CODE (desc))
-	{
-  	  case DEFINE_INSN:
-	    gen_insn (desc);
-	    break;
-
-	  case DEFINE_EXPAND:
-	    gen_expand (desc);
-	    break;
-
-	  case DEFINE_SPLIT:
-	    gen_split (desc);
-	    break;
-
-	  case DEFINE_PEEPHOLE2:
-	    have_peephole2_flag = 1;
-	    gen_peephole2 (desc);
-	    break;
-
-	  case DEFINE_PEEPHOLE:
-	    have_peephole_flag = 1;
-	    gen_peephole (desc);
-	    break;
-
-	  default:
-	    break;
-	}
-    }
+      case DEFINE_SPLIT:
+	gen_split (&info);
+	break;
+
+      case DEFINE_PEEPHOLE2:
+	have_peephole2_flag = 1;
+	gen_peephole2 (&info);
+	break;
+
+      case DEFINE_PEEPHOLE:
+	have_peephole_flag = 1;
+	gen_peephole (&info);
+	break;
+
+      default:
+	break;
+      }
 
   printf ("#define MAX_RECOG_OPERANDS %d\n", max_recog_operands + 1);
   printf ("#define MAX_DUP_OPERANDS %d\n", max_dup_operands);
Index: gcc/genemit.c
===================================================================
--- gcc/genemit.c	2015-07-12 14:18:21.158356783 +0100
+++ gcc/genemit.c	2015-07-12 14:18:26.679112278 +0100
@@ -28,9 +28,6 @@ Software Foundation; either version 3, o
 #include "gensupport.h"
 
 
-static int insn_code_number;
-static int insn_index_number;
-
 /* Data structure for recording the patterns of insns that have CLOBBERs.
    We use this to output a function that adds these CLOBBERs to a
    previously-allocated PARALLEL expression.  */
@@ -299,7 +296,7 @@ gen_emit_seq (rtvec vec, char *used)
 /* Generate the `gen_...' function for a DEFINE_INSN.  */
 
 static void
-gen_insn (rtx insn, int lineno)
+gen_insn (md_rtx_info *info)
 {
   struct pattern_stats stats;
   int i;
@@ -308,6 +305,7 @@ gen_insn (rtx insn, int lineno)
      registers or MATCH_SCRATCHes.  If so, store away the information for
      later.  */
 
+  rtx insn = info->def;
   if (XVEC (insn, 1))
     {
       int has_hard_reg = 0;
@@ -329,7 +327,7 @@ gen_insn (rtx insn, int lineno)
 	  struct clobber_ent *link = XNEW (struct clobber_ent);
 	  int j;
 
-	  link->code_number = insn_code_number;
+	  link->code_number = info->index;
 
 	  /* See if any previous CLOBBER_LIST entry is the same as this
 	     one.  */
@@ -383,12 +381,12 @@ gen_insn (rtx insn, int lineno)
   if (XSTR (insn, 0)[0] == 0 || XSTR (insn, 0)[0] == '*')
     return;
 
-  printf ("/* %s:%d */\n", read_md_filename, lineno);
+  printf ("/* %s:%d */\n", info->loc.filename, info->loc.lineno);
 
   /* Find out how many operands this function has.  */
   get_pattern_stats (&stats, XVEC (insn, 1));
   if (stats.max_dup_opno > stats.max_opno)
-    fatal ("match_dup operand number has no match_operand");
+    fatal_at (info->loc, "match_dup operand number has no match_operand");
 
   /* Output the function name and argument declarations.  */
   printf ("rtx\ngen_%s (", XSTR (insn, 0));
@@ -419,16 +417,18 @@ gen_insn (rtx insn, int lineno)
 /* Generate the `gen_...' function for a DEFINE_EXPAND.  */
 
 static void
-gen_expand (rtx expand)
+gen_expand (md_rtx_info *info)
 {
   struct pattern_stats stats;
   int i;
   char *used;
 
+  rtx expand = info->def;
   if (strlen (XSTR (expand, 0)) == 0)
-    fatal ("define_expand lacks a name");
+    fatal_at (info->loc, "define_expand lacks a name");
   if (XVEC (expand, 1) == 0)
-    fatal ("define_expand for %s lacks a pattern", XSTR (expand, 0));
+    fatal_at (info->loc, "define_expand for %s lacks a pattern",
+	      XSTR (expand, 0));
 
   /* Find out how many operands this function has.  */
   get_pattern_stats (&stats, XVEC (expand, 1));
@@ -517,21 +517,22 @@ gen_expand (rtx expand)
 /* Like gen_expand, but generates insns resulting from splitting SPLIT.  */
 
 static void
-gen_split (rtx split)
+gen_split (md_rtx_info *info)
 {
   struct pattern_stats stats;
   int i;
+  rtx split = info->def;
   const char *const name =
     ((GET_CODE (split) == DEFINE_PEEPHOLE2) ? "peephole2" : "split");
   const char *unused;
   char *used;
 
   if (XVEC (split, 0) == 0)
-    fatal ("define_%s (definition %d) lacks a pattern", name,
-	   insn_index_number);
+    fatal_at (info->loc, "%s lacks a pattern",
+	      GET_RTX_NAME (GET_CODE (split)));
   else if (XVEC (split, 2) == 0)
-    fatal ("define_%s (definition %d) lacks a replacement pattern", name,
-	   insn_index_number);
+    fatal_at (info->loc, "%s lacks a replacement pattern",
+	      GET_RTX_NAME (GET_CODE (split)));
 
   /* Find out how many operands this function has.  */
 
@@ -543,17 +544,18 @@ gen_split (rtx split)
   if (GET_CODE (split) == DEFINE_PEEPHOLE2)
     {
       printf ("extern rtx_insn *gen_%s_%d (rtx_insn *, rtx *);\n",
-	      name, insn_code_number);
-      printf ("rtx_insn *\ngen_%s_%d (rtx_insn *curr_insn ATTRIBUTE_UNUSED, rtx *operands%s)\n",
-	      name, insn_code_number, unused);
+	      name, info->index);
+      printf ("rtx_insn *\ngen_%s_%d (rtx_insn *curr_insn ATTRIBUTE_UNUSED,"
+	      " rtx *operands%s)\n",
+	      name, info->index, unused);
     }
   else
     {
       printf ("extern rtx_insn *gen_split_%d (rtx_insn *, rtx *);\n",
-	      insn_code_number);
+	      info->index);
       printf ("rtx_insn *\ngen_split_%d "
 	      "(rtx_insn *curr_insn ATTRIBUTE_UNUSED, rtx *operands%s)\n",
-	      insn_code_number, unused);
+	      info->index, unused);
     }
   printf ("{\n");
 
@@ -567,7 +569,7 @@ gen_split (rtx split)
 
   printf ("  if (dump_file)\n");
   printf ("    fprintf (dump_file, \"Splitting with gen_%s_%d\\n\");\n",
-	  name, insn_code_number);
+	  name, info->index);
 
   printf ("  start_sequence ();\n");
 
@@ -725,8 +727,6 @@ output_peephole2_scratches (rtx split)
 int
 main (int argc, char **argv)
 {
-  rtx desc;
-
   progname = "genemit";
 
   if (!init_rtx_reader_args (argc, argv))
@@ -735,9 +735,6 @@ main (int argc, char **argv)
   /* Assign sequential codes to all entries in the machine description
      in parallel with the tables in insn-output.c.  */
 
-  insn_code_number = 0;
-  insn_index_number = 0;
-
   printf ("/* Generated automatically by the program `genemit'\n\
 from the machine description file `md'.  */\n\n");
 
@@ -780,40 +777,32 @@ main (int argc, char **argv)
 
   /* Read the machine description.  */
 
-  while (1)
-    {
-      int line_no;
-
-      desc = read_md_rtx (&line_no, &insn_code_number);
-      if (desc == NULL)
+  md_rtx_info info;
+  while (read_md_rtx (&info))
+    switch (GET_CODE (info.def))
+      {
+      case DEFINE_INSN:
+	gen_insn (&info);
 	break;
 
-      switch (GET_CODE (desc))
-	{
-	case DEFINE_INSN:
-	  gen_insn (desc, line_no);
-	  break;
-
-	case DEFINE_EXPAND:
-	  printf ("/* %s:%d */\n", read_md_filename, line_no);
-	  gen_expand (desc);
-	  break;
+      case DEFINE_EXPAND:
+	printf ("/* %s:%d */\n", info.loc.filename, info.loc.lineno);
+	gen_expand (&info);
+	break;
 
-	case DEFINE_SPLIT:
-	  printf ("/* %s:%d */\n", read_md_filename, line_no);
-	  gen_split (desc);
-	  break;
+      case DEFINE_SPLIT:
+	printf ("/* %s:%d */\n", info.loc.filename, info.loc.lineno);
+	gen_split (&info);
+	break;
 
-	case DEFINE_PEEPHOLE2:
-	  printf ("/* %s:%d */\n", read_md_filename, line_no);
-	  gen_split (desc);
-	  break;
+      case DEFINE_PEEPHOLE2:
+	printf ("/* %s:%d */\n", info.loc.filename, info.loc.lineno);
+	gen_split (&info);
+	break;
 
-	default:
-	  break;
-	}
-      ++insn_index_number;
-    }
+      default:
+	break;
+      }
 
   /* Write out the routines to add CLOBBERs to a pattern and say whether they
      clobber a hard reg.  */
Index: gcc/genextract.c
===================================================================
--- gcc/genextract.c	2015-07-12 14:18:07.691911409 +0100
+++ gcc/genextract.c	2015-07-12 14:18:26.679112278 +0100
@@ -75,13 +75,11 @@ struct accum_extract
   vec<char> pathstr;
 };
 
-int line_no;
-
 /* Forward declarations.  */
-static void walk_rtx (rtx, struct accum_extract *);
+static void walk_rtx (md_rtx_info *, rtx, struct accum_extract *);
 
 static void
-gen_insn (rtx insn, int insn_code_number)
+gen_insn (md_rtx_info *info)
 {
   int i;
   unsigned int op_count, dup_count, j;
@@ -97,18 +95,19 @@ gen_insn (rtx insn, int insn_code_number
   /* Walk the insn's pattern, remembering at all times the path
      down to the walking point.  */
 
+  rtx insn = info->def;
   if (XVECLEN (insn, 1) == 1)
-    walk_rtx (XVECEXP (insn, 1, 0), &acc);
+    walk_rtx (info, XVECEXP (insn, 1, 0), &acc);
   else
     for (i = XVECLEN (insn, 1) - 1; i >= 0; i--)
       {
 	acc.pathstr.safe_push ('a' + i);
-	walk_rtx (XVECEXP (insn, 1, i), &acc);
+	walk_rtx (info, XVECEXP (insn, 1, i), &acc);
 	acc.pathstr.pop ();
       }
 
   link = XNEW (struct code_ptr);
-  link->insn_code = insn_code_number;
+  link->insn_code = info->index;
 
   /* See if we find something that already had this extraction method.  */
 
@@ -178,15 +177,17 @@ gen_insn (rtx insn, int insn_code_number
 /* Helper subroutine of walk_rtx: given a vec<locstr>, an index, and a
    string, insert the string at the index, which should either already
    exist and be NULL, or not yet exist within the vector.  In the latter
-   case the vector is enlarged as appropriate.  */
+   case the vector is enlarged as appropriate.  INFO describes the
+   containing define_* expression.  */
 static void
-VEC_safe_set_locstr (vec<locstr> *vp, unsigned int ix, char *str)
+VEC_safe_set_locstr (md_rtx_info *info, vec<locstr> *vp,
+		     unsigned int ix, char *str)
 {
   if (ix < (*vp).length ())
     {
       if ((*vp)[ix])
 	{
-	  message_with_line (line_no, "repeated operand number %d", ix);
+	  message_at (info->loc, "repeated operand number %d", ix);
 	  have_error = 1;
 	}
       else
@@ -213,7 +214,7 @@ VEC_char_to_string (vec<char> v)
 }
 
 static void
-walk_rtx (rtx x, struct accum_extract *acc)
+walk_rtx (md_rtx_info *info, rtx x, struct accum_extract *acc)
 {
   RTX_CODE code;
   int i, len, base;
@@ -233,20 +234,20 @@ walk_rtx (rtx x, struct accum_extract *a
 
     case MATCH_OPERAND:
     case MATCH_SCRATCH:
-      VEC_safe_set_locstr (&acc->oplocs, XINT (x, 0),
+      VEC_safe_set_locstr (info, &acc->oplocs, XINT (x, 0),
 			   VEC_char_to_string (acc->pathstr));
       break;
 
     case MATCH_OPERATOR:
     case MATCH_PARALLEL:
-      VEC_safe_set_locstr (&acc->oplocs, XINT (x, 0),
+      VEC_safe_set_locstr (info, &acc->oplocs, XINT (x, 0),
 			   VEC_char_to_string (acc->pathstr));
 
       base = (code == MATCH_OPERATOR ? '0' : 'a');
       for (i = XVECLEN (x, 2) - 1; i >= 0; i--)
 	{
 	  acc->pathstr.safe_push (base + i);
-	  walk_rtx (XVECEXP (x, 2, i), acc);
+	  walk_rtx (info, XVECEXP (x, 2, i), acc);
 	  acc->pathstr.pop ();
         }
       return;
@@ -264,7 +265,7 @@ walk_rtx (rtx x, struct accum_extract *a
       for (i = XVECLEN (x, 1) - 1; i >= 0; i--)
         {
 	  acc->pathstr.safe_push (base + i);
-	  walk_rtx (XVECEXP (x, 1, i), acc);
+	  walk_rtx (info, XVECEXP (x, 1, i), acc);
 	  acc->pathstr.pop ();
         }
       return;
@@ -280,7 +281,7 @@ walk_rtx (rtx x, struct accum_extract *a
       if (fmt[i] == 'e' || fmt[i] == 'u')
 	{
 	  acc->pathstr.safe_push ('0' + i);
-	  walk_rtx (XEXP (x, i), acc);
+	  walk_rtx (info, XEXP (x, i), acc);
 	  acc->pathstr.pop ();
 	}
       else if (fmt[i] == 'E')
@@ -289,7 +290,7 @@ walk_rtx (rtx x, struct accum_extract *a
 	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
 	    {
 	      acc->pathstr.safe_push ('a' + j);
-	      walk_rtx (XVECEXP (x, i, j), acc);
+	      walk_rtx (info, XVECEXP (x, i, j), acc);
 	      acc->pathstr.pop ();
 	    }
 	}
@@ -394,12 +395,10 @@ insn_extract (rtx_insn *insn)\n{\n\
 int
 main (int argc, char **argv)
 {
-  rtx desc;
   unsigned int i;
   struct extraction *p;
   struct code_ptr *link;
   const char *name;
-  int insn_code_number;
 
   progname = "genextract";
 
@@ -408,19 +407,26 @@ main (int argc, char **argv)
 
   /* Read the machine description.  */
 
-  while ((desc = read_md_rtx (&line_no, &insn_code_number)) != NULL)
-    {
-       if (GET_CODE (desc) == DEFINE_INSN)
-	 gen_insn (desc, insn_code_number);
+  md_rtx_info info;
+  while (read_md_rtx (&info))
+    switch (GET_CODE (info.def))
+      {
+      case DEFINE_INSN:
+	gen_insn (&info);
+	break;
 
-      else if (GET_CODE (desc) == DEFINE_PEEPHOLE)
+      case DEFINE_PEEPHOLE:
 	{
 	  struct code_ptr *link = XNEW (struct code_ptr);
 
-	  link->insn_code = insn_code_number;
+	  link->insn_code = info.index;
 	  link->next = peepholes;
 	  peepholes = link;
 	}
+	break;
+
+      default:
+	break;
     }
 
   if (have_error)
Index: gcc/genflags.c
===================================================================
--- gcc/genflags.c	2015-07-12 14:18:07.691911409 +0100
+++ gcc/genflags.c	2015-07-12 14:18:26.679112278 +0100
@@ -43,7 +43,6 @@ static void max_operand_1 (rtx);
 static int num_operands (rtx);
 static void gen_proto (rtx);
 static void gen_macro (const char *, int, int);
-static void gen_insn (int, rtx);
 
 /* Count the number of match_operand's found.  */
 
@@ -187,8 +186,9 @@ gen_proto (rtx insn)
 }
 
 static void
-gen_insn (int line_no, rtx insn)
+gen_insn (md_rtx_info *info)
 {
+  rtx insn = info->def;
   const char *name = XSTR (insn, 0);
   const char *p;
   const char *lt, *gt;
@@ -198,18 +198,15 @@ gen_insn (int line_no, rtx insn)
   lt = strchr (name, '<');
   if (lt && strchr (lt + 1, '>'))
     {
-      message_with_line (line_no, "unresolved iterator");
-      have_error = 1;
+      error_at (info->loc, "unresolved iterator");
       return;
     }
 
   gt = strchr (name, '>');
   if (lt || gt)
     {
-      message_with_line (line_no,
-			 "unmatched angle brackets, likely "
-			 "an error in iterator syntax");
-      have_error = 1;
+      error_at (info->loc, "unmatched angle brackets, likely "
+		"an error in iterator syntax");
       return;
     }
 
@@ -249,7 +246,6 @@ gen_insn (int line_no, rtx insn)
 int
 main (int argc, char **argv)
 {
-  rtx desc;
   rtx dummy;
   rtx *insns;
   rtx *insn_ptr;
@@ -271,16 +267,18 @@ main (int argc, char **argv)
 
   /* Read the machine description.  */
 
-  while (1)
-    {
-      int line_no, insn_code_number = 0;
+  md_rtx_info info;
+  while (read_md_rtx (&info))
+    switch (GET_CODE (info.def))
+      {
+      case DEFINE_INSN:
+      case DEFINE_EXPAND:
+	gen_insn (&info);
+	break;
 
-      desc = read_md_rtx (&line_no, &insn_code_number);
-      if (desc == NULL)
+      default:
 	break;
-      if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
-	gen_insn (line_no, desc);
-    }
+      }
 
   /* Print out the prototypes now.  */
   dummy = (rtx) 0;
Index: gcc/genmddump.c
===================================================================
--- gcc/genmddump.c	2015-07-12 14:18:07.691911409 +0100
+++ gcc/genmddump.c	2015-07-12 14:18:26.679112278 +0100
@@ -40,22 +40,17 @@ extern int main (int, char **);
 int
 main (int argc, char **argv)
 {
-  rtx desc;
-  int pattern_lineno;
-  int code; /* not used */
   progname = "genmddump";
 
   if (!init_rtx_reader_args (argc, argv))
     return (FATAL_EXIT_CODE);
 
   /* Read the machine description.  */
-  while (1)
+  md_rtx_info info;
+  while (read_md_rtx (&info))
     {
-      desc = read_md_rtx (&pattern_lineno, &code);
-      if (desc == NULL)
-	break;
-      printf (";; %s: %d\n", read_md_filename, pattern_lineno);
-      print_inline_rtx (stdout, desc, 0);
+      printf (";; %s: %d\n", info.loc.filename, info.loc.lineno);
+      print_inline_rtx (stdout, info.def, 0);
       printf ("\n\n");
     }
 
Index: gcc/genopinit.c
===================================================================
--- gcc/genopinit.c	2015-07-12 14:18:20.787373213 +0100
+++ gcc/genopinit.c	2015-07-12 14:18:26.679112278 +0100
@@ -243,8 +243,9 @@ match_pattern (pattern *p, const char *n
 }
 
 static void
-gen_insn (rtx insn)
+gen_insn (md_rtx_info *info)
 {
+  rtx insn = info->def;
   const char *name = XSTR (insn, 0);
   pattern p;
   unsigned pindex;
@@ -346,15 +347,18 @@ main (int argc, char **argv)
   s_file = open_outfile (source_file_name);
 
   /* Read the machine description.  */
-  while (1)
-    {
-      int line_no, insn_code_number = 0;
-      rtx desc = read_md_rtx (&line_no, &insn_code_number);
-      if (desc == NULL)
+  md_rtx_info info;
+  while (read_md_rtx (&info))
+    switch (GET_CODE (info.def))
+      {
+      case DEFINE_INSN:
+      case DEFINE_EXPAND:
+	gen_insn (&info);
 	break;
-      if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
-	gen_insn (desc);
-    }
+
+      default:
+	break;
+      }
 
   /* Sort the collected patterns.  */
   patterns.qsort (pattern_cmp);
Index: gcc/genoutput.c
===================================================================
--- gcc/genoutput.c	2015-07-12 14:18:26.659113164 +0100
+++ gcc/genoutput.c	2015-07-12 14:18:26.680112234 +0100
@@ -103,12 +103,6 @@ static char general_mem[] = { TARGET_MEM
 static int n_occurrences		(int, const char *);
 static const char *strip_whitespace	(const char *);
 
-/* insns in the machine description are assigned sequential code numbers
-   that are used by insn-recog.c (produced by genrecog) to communicate
-   to insn-output.c (produced by this program).  */
-
-static int next_code_number;
-
 /* This counts all operands used in the md file.  The first is null.  */
 
 static int next_operand_number = 1;
@@ -184,10 +178,6 @@ static void place_operands (struct data
 static void process_template (struct data *, const char *);
 static void validate_insn_alternatives (struct data *);
 static void validate_insn_operands (struct data *);
-static void gen_insn (rtx, int);
-static void gen_peephole (rtx, int);
-static void gen_expand (rtx, int);
-static void gen_split (rtx, int);
 
 struct constraint_data
 {
@@ -205,7 +195,7 @@ static const char indep_constraints[] =
 constraints_by_letter_table[1 << CHAR_BIT];
 
 static int mdep_constraint_len (const char *, file_location, int);
-static void note_constraint (rtx, int);
+static void note_constraint (md_rtx_info *);
 
 static void
 output_prologue (void)
@@ -861,14 +851,15 @@ validate_optab_operands (struct data *d)
    a hairy output action, output a function for now.  */
 
 static void
-gen_insn (rtx insn, int lineno)
+gen_insn (md_rtx_info *info)
 {
   struct pattern_stats stats;
+  rtx insn = info->def;
   data *d = new data;
   int i;
 
-  d->code_number = next_code_number;
-  d->loc = file_location (read_md_filename, lineno);
+  d->code_number = info->index;
+  d->loc = info->loc;
   if (XSTR (insn, 0)[0])
     d->name = XSTR (insn, 0);
   else
@@ -902,14 +893,14 @@ gen_insn (rtx insn, int lineno)
    If the insn has a hairy output action, output it now.  */
 
 static void
-gen_peephole (rtx peep, int lineno)
+gen_peephole (md_rtx_info *info)
 {
   struct pattern_stats stats;
   data *d = new data;
   int i;
 
-  d->code_number = next_code_number;
-  d->loc = file_location (read_md_filename, lineno);
+  d->code_number = info->index;
+  d->loc = info->loc;
   d->name = 0;
 
   /* Build up the list in the same order as the insns are seen
@@ -923,6 +914,7 @@ gen_peephole (rtx peep, int lineno)
   /* Get the number of operands by scanning all the patterns of the
      peephole optimizer.  But ignore all the rest of the information
      thus obtained.  */
+  rtx peep = info->def;
   for (i = 0; i < XVECLEN (peep, 0); i++)
     scan_operands (d, XVECEXP (peep, 0, i), 0, 0);
 
@@ -940,14 +932,15 @@ gen_peephole (rtx peep, int lineno)
    only for the purposes of `insn_gen_function'.  */
 
 static void
-gen_expand (rtx insn, int lineno)
+gen_expand (md_rtx_info *info)
 {
   struct pattern_stats stats;
+  rtx insn = info->def;
   data *d = new data;
   int i;
 
-  d->code_number = next_code_number;
-  d->loc = file_location (read_md_filename, lineno);
+  d->code_number = info->index;
+  d->loc = info->loc;
   if (XSTR (insn, 0)[0])
     d->name = XSTR (insn, 0);
   else
@@ -984,14 +977,14 @@ gen_expand (rtx insn, int lineno)
    only for reasons of consistency and to simplify genrecog.  */
 
 static void
-gen_split (rtx split, int lineno)
+gen_split (md_rtx_info *info)
 {
   struct pattern_stats stats;
   data *d = new data;
   int i;
 
-  d->code_number = next_code_number;
-  d->loc = file_location (read_md_filename, lineno);
+  d->code_number = info->index;
+  d->loc = info->loc;
   d->name = 0;
 
   /* Build up the list in the same order as the insns are seen
@@ -1005,6 +998,7 @@ gen_split (rtx split, int lineno)
   /* Get the number of operands by scanning all the patterns of the
      split patterns.  But ignore all the rest of the information thus
      obtained.  */
+  rtx split = info->def;
   for (i = 0; i < XVECLEN (split, 0); i++)
     scan_operands (d, XVECEXP (split, 0, i), 0, 0);
 
@@ -1034,8 +1028,6 @@ extern int main (int, char **);
 int
 main (int argc, char **argv)
 {
-  rtx desc;
-
   progname = "genoutput";
 
   init_insn_for_nothing ();
@@ -1047,44 +1039,37 @@ main (int argc, char **argv)
 
   /* Read the machine description.  */
 
-  while (1)
-    {
-      int line_no;
-
-      desc = read_md_rtx (&line_no, &next_code_number);
-      if (desc == NULL)
+  md_rtx_info info;
+  while (read_md_rtx (&info))
+    switch (GET_CODE (info.def))
+      {
+      case DEFINE_INSN:
+	gen_insn (&info);
 	break;
 
-      switch (GET_CODE (desc))
-	{
-	case DEFINE_INSN:
-	  gen_insn (desc, line_no);
-	  break;
-
-	case DEFINE_PEEPHOLE:
-	  gen_peephole (desc, line_no);
-	  break;
+      case DEFINE_PEEPHOLE:
+	gen_peephole (&info);
+	break;
 
-	case DEFINE_EXPAND:
-	  gen_expand (desc, line_no);
-	  break;
+      case DEFINE_EXPAND:
+	gen_expand (&info);
+	break;
 
-	case DEFINE_SPLIT:
-	case DEFINE_PEEPHOLE2:
-	  gen_split (desc, line_no);
-	  break;
+      case DEFINE_SPLIT:
+      case DEFINE_PEEPHOLE2:
+	gen_split (&info);
+	break;
 
-	case DEFINE_CONSTRAINT:
-	case DEFINE_REGISTER_CONSTRAINT:
-	case DEFINE_ADDRESS_CONSTRAINT:
-	case DEFINE_MEMORY_CONSTRAINT:
-	  note_constraint (desc, line_no);
-	  break;
+      case DEFINE_CONSTRAINT:
+      case DEFINE_REGISTER_CONSTRAINT:
+      case DEFINE_ADDRESS_CONSTRAINT:
+      case DEFINE_MEMORY_CONSTRAINT:
+	note_constraint (&info);
+	break;
 
-	default:
-	  break;
-	}
-    }
+      default:
+	break;
+      }
 
   printf ("\n\n");
   output_operand_data ();
@@ -1134,15 +1119,14 @@ strip_whitespace (const char *s)
   return q;
 }
 
-/* Record just enough information about a constraint to allow checking
-   of operand constraint strings above, in validate_insn_alternatives.
-   Does not validate most properties of the constraint itself; does
-   enforce no duplicate names, no overlap with MI constraints, and no
-   prefixes.  EXP is the define_*constraint form, LINENO the line number
-   reported by the reader.  */
+/* Record just enough information about the constraint in *INFO to allow
+   checking of operand constraint strings above, in validate_insn_alternatives.
+   Does not validate most properties of the constraint itself; does enforce
+   no duplicate names, no overlap with MI constraints, and no prefixes.  */
 static void
-note_constraint (rtx exp, int lineno)
+note_constraint (md_rtx_info *info)
 {
+  rtx exp = info->def;
   const char *name = XSTR (exp, 0);
   struct constraint_data **iter, **slot, *new_cdata;
 
@@ -1153,12 +1137,12 @@ note_constraint (rtx exp, int lineno)
   if (strchr (indep_constraints, name[0]))
     {
       if (name[1] == '\0')
-	error_with_line (lineno, "constraint letter '%s' cannot be "
-			 "redefined by the machine description", name);
+	error_at (info->loc, "constraint letter '%s' cannot be "
+		  "redefined by the machine description", name);
       else
-	error_with_line (lineno, "constraint name '%s' cannot be defined by "
-			 "the machine description, as it begins with '%c'",
-			 name, name[0]);
+	error_at (info->loc, "constraint name '%s' cannot be defined by "
+		  "the machine description, as it begins with '%c'",
+		  name, name[0]);
       return;
     }
 
@@ -1175,20 +1159,20 @@ note_constraint (rtx exp, int lineno)
 
       if (!strcmp ((*iter)->name, name))
 	{
-	  error_with_line (lineno, "redefinition of constraint '%s'", name);
+	  error_at (info->loc, "redefinition of constraint '%s'", name);
 	  message_at ((*iter)->loc, "previous definition is here");
 	  return;
 	}
       else if (!strncmp ((*iter)->name, name, (*iter)->namelen))
 	{
-	  error_with_line (lineno, "defining constraint '%s' here", name);
+	  error_at (info->loc, "defining constraint '%s' here", name);
 	  message_at ((*iter)->loc, "renders constraint '%s' "
 		      "(defined here) a prefix", (*iter)->name);
 	  return;
 	}
       else if (!strncmp ((*iter)->name, name, namelen))
 	{
-	  error_with_line (lineno, "constraint '%s' is a prefix", name);
+	  error_at (info->loc, "constraint '%s' is a prefix", name);
 	  message_at ((*iter)->loc, "of constraint '%s' "
 		      "(defined here)", (*iter)->name);
 	  return;
@@ -1199,7 +1183,7 @@ note_constraint (rtx exp, int lineno)
   new (new_cdata) constraint_data ();
   strcpy (CONST_CAST (char *, new_cdata->name), name);
   new_cdata->namelen = namelen;
-  new_cdata->loc = file_location (read_md_filename, lineno);
+  new_cdata->loc = info->loc;
   new_cdata->next_this_letter = *slot;
   *slot = new_cdata;
 }
Index: gcc/genpeep.c
===================================================================
--- gcc/genpeep.c	2015-07-12 14:18:22.088315597 +0100
+++ gcc/genpeep.c	2015-07-12 14:18:26.680112234 +0100
@@ -46,14 +46,14 @@ struct link
 
 static int n_operands;
 
-static void gen_peephole (rtx, int);
 static void match_rtx (rtx, struct link *, int);
 static void print_path (struct link *);
 static void print_code (RTX_CODE);
 
 static void
-gen_peephole (rtx peep, int insn_code_number)
+gen_peephole (md_rtx_info *info)
 {
+  rtx peep = info->def;
   int ninsns = XVECLEN (peep, 0);
   int i;
 
@@ -66,16 +66,14 @@ gen_peephole (rtx peep, int insn_code_nu
       if (i > 0)
 	{
 	  printf ("  do { insn = NEXT_INSN (insn);\n");
-	  printf ("       if (insn == 0) goto L%d; }\n",
-		  insn_code_number);
+	  printf ("       if (insn == 0) goto L%d; }\n", info->index);
 	  printf ("  while (NOTE_P (insn)\n");
 	  printf ("\t || (NONJUMP_INSN_P (insn)\n");
 	  printf ("\t     && (GET_CODE (PATTERN (insn)) == USE\n");
 	  printf ("\t\t || GET_CODE (PATTERN (insn)) == CLOBBER)));\n");
 
 	  printf ("  if (LABEL_P (insn)\n\
-      || BARRIER_P (insn))\n    goto L%d;\n",
-		  insn_code_number);
+      || BARRIER_P (insn))\n    goto L%d;\n", info->index);
 	}
 
       printf ("  pat = PATTERN (insn);\n");
@@ -83,7 +81,7 @@ gen_peephole (rtx peep, int insn_code_nu
       /* Walk the insn's pattern, remembering at all times the path
 	 down to the walking point.  */
 
-      match_rtx (XVECEXP (peep, 0, i), NULL, insn_code_number);
+      match_rtx (XVECEXP (peep, 0, i), NULL, info->index);
     }
 
   /* We get this far if the pattern matches.
@@ -91,7 +89,7 @@ gen_peephole (rtx peep, int insn_code_nu
 
   if (XSTR (peep, 1) && XSTR (peep, 1)[0])
     printf ("  if (! (%s)) goto L%d;\n",
-	    XSTR (peep, 1), insn_code_number);
+	    XSTR (peep, 1), info->index);
 
   /* If that matches, construct new pattern and put it in the first insn.
      This new pattern will never be matched.
@@ -103,8 +101,7 @@ gen_peephole (rtx peep, int insn_code_nu
 
   /* Record this define_peephole's insn code in the insn,
      as if it had been recognized to match this.  */
-  printf ("  INSN_CODE (ins1) = %d;\n",
-	  insn_code_number);
+  printf ("  INSN_CODE (ins1) = %d;\n", info->index);
 
   /* Delete the remaining insns.  */
   if (ninsns > 1)
@@ -114,7 +111,7 @@ gen_peephole (rtx peep, int insn_code_nu
      cannot be zero.  */
   printf ("  return NEXT_INSN (insn);\n");
 
-  printf (" L%d:\n\n", insn_code_number);
+  printf (" L%d:\n\n", info->index);
 }
 
 static void
@@ -348,8 +345,6 @@ extern int main (int, char **);
 int
 main (int argc, char **argv)
 {
-  rtx desc;
-
   max_opno = -1;
 
   progname = "genpeep";
@@ -394,18 +389,17 @@ main (int argc, char **argv)
 
   /* Read the machine description.  */
 
-  while (1)
-    {
-      int line_no;
-      int insn_code_number;
-
-      desc = read_md_rtx (&line_no, &insn_code_number);
-      if (desc == NULL)
+  md_rtx_info info;
+  while (read_md_rtx (&info))
+    switch (GET_CODE (info.def))
+      {
+      case DEFINE_PEEPHOLE:
+	gen_peephole (&info);
 	break;
 
-      if (GET_CODE (desc) == DEFINE_PEEPHOLE)
-	gen_peephole (desc, insn_code_number);
-    }
+      default:
+	break;
+      }
 
   printf ("  return 0;\n}\n\n");
 
Index: gcc/genpreds.c
===================================================================
--- gcc/genpreds.c	2015-07-12 14:18:26.667112809 +0100
+++ gcc/genpreds.c	2015-07-12 14:18:26.680112234 +0100
@@ -91,10 +91,9 @@ validate_exp (rtx exp, const char *name,
 /* Predicates are defined with (define_predicate) or
    (define_special_predicate) expressions in the machine description.  */
 static void
-process_define_predicate (rtx defn, int lineno)
+process_define_predicate (md_rtx_info *info)
 {
-  validate_exp (XEXP (defn, 1), XSTR (defn, 0),
-		file_location (read_md_filename, lineno));
+  validate_exp (XEXP (info->def, 1), XSTR (info->def, 0), info->loc);
 }
 
 /* Given a predicate, if it has an embedded C block, write the block
@@ -936,20 +935,20 @@ add_constraint (const char *name, const
 /* Process a DEFINE_CONSTRAINT, DEFINE_MEMORY_CONSTRAINT, or
    DEFINE_ADDRESS_CONSTRAINT expression, C.  */
 static void
-process_define_constraint (rtx c, int lineno)
+process_define_constraint (md_rtx_info *info)
 {
-  add_constraint (XSTR (c, 0), 0, XEXP (c, 2),
-		  GET_CODE (c) == DEFINE_MEMORY_CONSTRAINT,
-		  GET_CODE (c) == DEFINE_ADDRESS_CONSTRAINT,
-		  file_location (read_md_filename, lineno));
+  add_constraint (XSTR (info->def, 0), 0, XEXP (info->def, 2),
+		  GET_CODE (info->def) == DEFINE_MEMORY_CONSTRAINT,
+		  GET_CODE (info->def) == DEFINE_ADDRESS_CONSTRAINT,
+		  info->loc);
 }
 
 /* Process a DEFINE_REGISTER_CONSTRAINT expression, C.  */
 static void
-process_define_register_constraint (rtx c, int lineno)
+process_define_register_constraint (md_rtx_info *info)
 {
-  add_constraint (XSTR (c, 0), XSTR (c, 1), 0, false, false,
-		  file_location (read_md_filename, lineno));
+  add_constraint (XSTR (info->def, 0), XSTR (info->def, 1),
+		  0, false, false, info->loc);
 }
 
 /* Put the constraints into enum order.  We want to keep constraints
@@ -1584,31 +1583,29 @@ parse_option (const char *opt)
 int
 main (int argc, char **argv)
 {
-  rtx defn;
-  int pattern_lineno, next_insn_code = 0;
-
   progname = argv[0];
   if (argc <= 1)
     fatal ("no input file name");
   if (!init_rtx_reader_args_cb (argc, argv, parse_option))
     return FATAL_EXIT_CODE;
 
-  while ((defn = read_md_rtx (&pattern_lineno, &next_insn_code)) != 0)
-    switch (GET_CODE (defn))
+  md_rtx_info info;
+  while (read_md_rtx (&info))
+    switch (GET_CODE (info.def))
       {
       case DEFINE_PREDICATE:
       case DEFINE_SPECIAL_PREDICATE:
-	process_define_predicate (defn, pattern_lineno);
+	process_define_predicate (&info);
 	break;
 
       case DEFINE_CONSTRAINT:
       case DEFINE_MEMORY_CONSTRAINT:
       case DEFINE_ADDRESS_CONSTRAINT:
-	process_define_constraint (defn, pattern_lineno);
+	process_define_constraint (&info);
 	break;
 
       case DEFINE_REGISTER_CONSTRAINT:
-	process_define_register_constraint (defn, pattern_lineno);
+	process_define_register_constraint (&info);
 	break;
 
       default:
Index: gcc/genrecog.c
===================================================================
--- gcc/genrecog.c	2015-07-12 14:18:20.370391681 +0100
+++ gcc/genrecog.c	2015-07-12 20:52:12.069368786 +0100
@@ -250,12 +250,6 @@ enum routine_type {
   SUBPATTERN, RECOG, SPLIT, PEEPHOLE2
 };
 
-/* Next number to use as an insn_code.  */
-static int next_insn_code;
-
-/* The line number of the start of the pattern currently being processed.  */
-static int pattern_lineno;
-
 /* The root position (x0).  */
 static struct position root_pos;
 
@@ -469,12 +463,13 @@ constraints_supported_in_insn_p (rtx ins
 	   || GET_CODE (insn) == DEFINE_PEEPHOLE2);
 }
 
-/* Check for various errors in patterns.  SET is nonnull for a destination,
-   and is the complete set pattern.  SET_CODE is '=' for normal sets, and
-   '+' within a context that requires in-out constraints.  */
+/* Check for various errors in PATTERN, which is part of INFO.
+   SET is nonnull for a destination, and is the complete set pattern.
+   SET_CODE is '=' for normal sets, and '+' within a context that
+   requires in-out constraints.  */
 
 static void
-validate_pattern (rtx pattern, rtx insn, rtx set, int set_code)
+validate_pattern (rtx pattern, md_rtx_info *info, rtx set, int set_code)
 {
   const char *fmt;
   RTX_CODE code;
@@ -488,13 +483,12 @@ validate_pattern (rtx pattern, rtx insn,
       {
 	const char constraints0 = XSTR (pattern, 1)[0];
 
-	if (!constraints_supported_in_insn_p (insn))
+	if (!constraints_supported_in_insn_p (info->def))
 	  {
 	    if (constraints0)
 	      {
-		error_with_line (pattern_lineno,
-				 "constraints not supported in %s",
-				 rtx_name[GET_CODE (insn)]);
+		error_at (info->loc, "constraints not supported in %s",
+			  GET_RTX_NAME (GET_CODE (info->def)));
 	      }
 	    return;
 	  }
@@ -506,19 +500,17 @@ validate_pattern (rtx pattern, rtx insn,
 	    && constraints0 != '='
 	    && constraints0 != '+')
 	  {
-	    error_with_line (pattern_lineno,
-			     "operand %d missing output reload",
-			     XINT (pattern, 0));
+	    error_at (info->loc, "operand %d missing output reload",
+		      XINT (pattern, 0));
 	  }
 	return;
       }
     case MATCH_DUP:
     case MATCH_OP_DUP:
     case MATCH_PAR_DUP:
-      if (find_operand (insn, XINT (pattern, 0), pattern) == pattern)
-	error_with_line (pattern_lineno,
-			 "operand %i duplicated before defined",
-			 XINT (pattern, 0));
+      if (find_operand (info->def, XINT (pattern, 0), pattern) == pattern)
+	error_at (info->loc, "operand %i duplicated before defined",
+		  XINT (pattern, 0));
       break;
     case MATCH_OPERAND:
     case MATCH_OPERATOR:
@@ -527,17 +519,16 @@ validate_pattern (rtx pattern, rtx insn,
 	const struct pred_data *pred;
 	const char *c_test;
 
-	if (GET_CODE (insn) == DEFINE_INSN)
-	  c_test = XSTR (insn, 2);
+	if (GET_CODE (info->def) == DEFINE_INSN)
+	  c_test = XSTR (info->def, 2);
 	else
-	  c_test = XSTR (insn, 1);
+	  c_test = XSTR (info->def, 1);
 
 	if (pred_name[0] != 0)
 	  {
 	    pred = lookup_predicate (pred_name);
 	    if (!pred)
-	      error_with_line (pattern_lineno, "unknown predicate '%s'",
-			       pred_name);
+	      error_at (info->loc, "unknown predicate '%s'", pred_name);
 	  }
 	else
 	  pred = 0;
@@ -547,13 +538,12 @@ validate_pattern (rtx pattern, rtx insn,
 	    const char *constraints = XSTR (pattern, 2);
 	    const char constraints0 = constraints[0];
 
-	    if (!constraints_supported_in_insn_p (insn))
+	    if (!constraints_supported_in_insn_p (info->def))
 	      {
 		if (constraints0)
 		  {
-		    error_with_line (pattern_lineno,
-				     "constraints not supported in %s",
-				     rtx_name[GET_CODE (insn)]);
+		    error_at (info->loc, "constraints not supported in %s",
+			      GET_RTX_NAME (GET_CODE (info->def)));
 		  }
 	      }
 
@@ -567,17 +557,16 @@ validate_pattern (rtx pattern, rtx insn,
 		    /* If we've only got an output reload for this operand,
 		       we'd better have a matching input operand.  */
 		    else if (constraints0 == '='
-			     && find_matching_operand (insn, XINT (pattern, 0)))
+			     && find_matching_operand (info->def,
+						       XINT (pattern, 0)))
 		      ;
 		    else
-		      error_with_line (pattern_lineno,
-				       "operand %d missing in-out reload",
-				       XINT (pattern, 0));
+		      error_at (info->loc, "operand %d missing in-out reload",
+				XINT (pattern, 0));
 		  }
 		else if (constraints0 != '=' && constraints0 != '+')
-		  error_with_line (pattern_lineno,
-				   "operand %d missing output reload",
-				   XINT (pattern, 0));
+		  error_at (info->loc, "operand %d missing output reload",
+			    XINT (pattern, 0));
 	      }
 
 	    /* For matching constraint in MATCH_OPERAND, the digit must be a
@@ -597,10 +586,9 @@ validate_pattern (rtx pattern, rtx insn,
 
 		    sscanf (constraints, "%d", &val);
 		    if (val >= XINT (pattern, 0))
-		      error_with_line (pattern_lineno,
-				       "constraint digit %d is not smaller than"
-				       " operand %d",
-				       val, XINT (pattern, 0));
+		      error_at (info->loc, "constraint digit %d is not"
+				" smaller than operand %d",
+				val, XINT (pattern, 0));
 		  }
 
 		while (constraints[0] && constraints[0] != ',')
@@ -612,9 +600,8 @@ validate_pattern (rtx pattern, rtx insn,
 	   while not likely to occur at runtime, results in less efficient
 	   code from insn-recog.c.  */
 	if (set && pred && pred->allows_non_lvalue)
-	  error_with_line (pattern_lineno,
-			   "destination operand %d allows non-lvalue",
-			   XINT (pattern, 0));
+	  error_at (info->loc, "destination operand %d allows non-lvalue",
+		    XINT (pattern, 0));
 
 	/* A modeless MATCH_OPERAND can be handy when we can check for
 	   multiple modes in the c_test.  In most other cases, it is a
@@ -626,7 +613,7 @@ validate_pattern (rtx pattern, rtx insn,
 
 	if (GET_MODE (pattern) == VOIDmode
 	    && code == MATCH_OPERAND
-	    && GET_CODE (insn) == DEFINE_INSN
+	    && GET_CODE (info->def) == DEFINE_INSN
 	    && pred
 	    && !pred->special
 	    && pred->allows_non_const
@@ -634,9 +621,8 @@ validate_pattern (rtx pattern, rtx insn,
 	    && ! (set
 		  && GET_CODE (set) == SET
 		  && GET_CODE (SET_SRC (set)) == CALL))
-	  message_with_line (pattern_lineno,
-			     "warning: operand %d missing mode?",
-			     XINT (pattern, 0));
+	  message_at (info->loc, "warning: operand %d missing mode?",
+		      XINT (pattern, 0));
 	return;
       }
 
@@ -658,12 +644,12 @@ validate_pattern (rtx pattern, rtx insn,
 	if (GET_CODE (dest) == MATCH_DUP
 	    || GET_CODE (dest) == MATCH_OP_DUP
 	    || GET_CODE (dest) == MATCH_PAR_DUP)
-	  dest = find_operand (insn, XINT (dest, 0), NULL);
+	  dest = find_operand (info->def, XINT (dest, 0), NULL);
 
 	if (GET_CODE (src) == MATCH_DUP
 	    || GET_CODE (src) == MATCH_OP_DUP
 	    || GET_CODE (src) == MATCH_PAR_DUP)
-	  src = find_operand (insn, XINT (src, 0), NULL);
+	  src = find_operand (info->def, XINT (src, 0), NULL);
 
 	dmode = GET_MODE (dest);
 	smode = GET_MODE (src);
@@ -677,9 +663,8 @@ validate_pattern (rtx pattern, rtx insn,
         /* The operands of a SET must have the same mode unless one
 	   is VOIDmode.  */
         else if (dmode != VOIDmode && smode != VOIDmode && dmode != smode)
-	  error_with_line (pattern_lineno,
-			   "mode mismatch in set: %smode vs %smode",
-			   GET_MODE_NAME (dmode), GET_MODE_NAME (smode));
+	  error_at (info->loc, "mode mismatch in set: %smode vs %smode",
+		    GET_MODE_NAME (dmode), GET_MODE_NAME (smode));
 
 	/* If only one of the operands is VOIDmode, and PC or CC0 is
 	   not involved, it's probably a mistake.  */
@@ -694,36 +679,34 @@ validate_pattern (rtx pattern, rtx insn,
 	  {
 	    const char *which;
 	    which = (dmode == VOIDmode ? "destination" : "source");
-	    message_with_line (pattern_lineno,
-			       "warning: %s missing a mode?", which);
+	    message_at (info->loc, "warning: %s missing a mode?", which);
 	  }
 
 	if (dest != SET_DEST (pattern))
-	  validate_pattern (dest, insn, pattern, '=');
-	validate_pattern (SET_DEST (pattern), insn, pattern, '=');
-        validate_pattern (SET_SRC (pattern), insn, NULL_RTX, 0);
+	  validate_pattern (dest, info, pattern, '=');
+	validate_pattern (SET_DEST (pattern), info, pattern, '=');
+        validate_pattern (SET_SRC (pattern), info, NULL_RTX, 0);
         return;
       }
 
     case CLOBBER:
-      validate_pattern (SET_DEST (pattern), insn, pattern, '=');
+      validate_pattern (SET_DEST (pattern), info, pattern, '=');
       return;
 
     case ZERO_EXTRACT:
-      validate_pattern (XEXP (pattern, 0), insn, set, set ? '+' : 0);
-      validate_pattern (XEXP (pattern, 1), insn, NULL_RTX, 0);
-      validate_pattern (XEXP (pattern, 2), insn, NULL_RTX, 0);
+      validate_pattern (XEXP (pattern, 0), info, set, set ? '+' : 0);
+      validate_pattern (XEXP (pattern, 1), info, NULL_RTX, 0);
+      validate_pattern (XEXP (pattern, 2), info, NULL_RTX, 0);
       return;
 
     case STRICT_LOW_PART:
-      validate_pattern (XEXP (pattern, 0), insn, set, set ? '+' : 0);
+      validate_pattern (XEXP (pattern, 0), info, set, set ? '+' : 0);
       return;
 
     case LABEL_REF:
       if (GET_MODE (LABEL_REF_LABEL (pattern)) != VOIDmode)
-	error_with_line (pattern_lineno,
-			 "operand to label_ref %smode not VOIDmode",
-			 GET_MODE_NAME (GET_MODE (LABEL_REF_LABEL (pattern))));
+	error_at (info->loc, "operand to label_ref %smode not VOIDmode",
+		  GET_MODE_NAME (GET_MODE (LABEL_REF_LABEL (pattern))));
       break;
 
     default:
@@ -737,12 +720,12 @@ validate_pattern (rtx pattern, rtx insn,
       switch (fmt[i])
 	{
 	case 'e': case 'u':
-	  validate_pattern (XEXP (pattern, i), insn, NULL_RTX, 0);
+	  validate_pattern (XEXP (pattern, i), info, NULL_RTX, 0);
 	  break;
 
 	case 'E':
 	  for (j = 0; j < XVECLEN (pattern, i); j++)
-	    validate_pattern (XVECEXP (pattern, i, j), insn, NULL_RTX, 0);
+	    validate_pattern (XVECEXP (pattern, i, j), info, NULL_RTX, 0);
 	  break;
 
 	case 'i': case 'r': case 'w': case '0': case 's':
@@ -3823,7 +3806,7 @@ predicate_name (rtx match_rtx)
    TOP_PATTERN is the overall pattern, as passed to match_pattern_1.  */
 
 static state *
-match_pattern_2 (state *s, rtx top_pattern, position *pos, rtx pattern)
+match_pattern_2 (state *s, md_rtx_info *info, position *pos, rtx pattern)
 {
   auto_vec <pattern_pos, 32> worklist;
   auto_vec <pattern_pos, 32> pred_and_mode_tests;
@@ -3848,7 +3831,7 @@ match_pattern_2 (state *s, rtx top_patte
 	  dup_tests.safe_push (pattern_pos (pattern, pos));
 
 	  /* Use the same code check as the original operand.  */
-	  pattern = find_operand (top_pattern, XINT (pattern, 0), NULL_RTX);
+	  pattern = find_operand (info->def, XINT (pattern, 0), NULL_RTX);
 	  /* Fall through.  */
 
 	case MATCH_PARALLEL:
@@ -3865,16 +3848,13 @@ match_pattern_2 (state *s, rtx top_patte
 		if (code == GET_CODE (pattern))
 		  {
 		    if (!pred)
-		      error_with_line (pattern_lineno,
-				       "unknown predicate '%s'"
-				       " in '%s' expression",
-				       pred_name, GET_RTX_NAME (code));
+		      error_at (info->loc, "unknown predicate '%s' used in %s",
+				pred_name, GET_RTX_NAME (code));
 		    else if (code == MATCH_PARALLEL
 			     && pred->singleton != PARALLEL)
-		      error_with_line (pattern_lineno,
-				       "predicate '%s' used in match_parallel"
-				       " does not allow only PARALLEL",
-				       pred->name);
+		      error_at (info->loc, "predicate '%s' used in"
+				" match_parallel does not allow only PARALLEL",
+				pred->name);
 		  }
 	      }
 
@@ -4106,7 +4086,7 @@ match_pattern_2 (state *s, rtx top_patte
    to match, otherwise it is a single instruction pattern.  */
 
 static void
-match_pattern_1 (state *s, rtx top_pattern, const char *c_test,
+match_pattern_1 (state *s, md_rtx_info *info, rtx pattern, const char *c_test,
 		 acceptance_type acceptance)
 {
   if (acceptance.type == PEEPHOLE2)
@@ -4114,15 +4094,15 @@ match_pattern_1 (state *s, rtx top_patte
       /* Match each individual instruction.  */
       position **subpos_ptr = &peep2_insn_pos_list;
       int count = 0;
-      for (int i = 0; i < XVECLEN (top_pattern, 0); ++i)
+      for (int i = 0; i < XVECLEN (pattern, 0); ++i)
 	{
-	  rtx x = XVECEXP (top_pattern, 0, i);
+	  rtx x = XVECEXP (pattern, 0, i);
 	  position *subpos = next_position (subpos_ptr, &root_pos,
 					    POS_PEEP2_INSN, count);
 	  if (count > 0)
 	    s = add_decision (s, rtx_test::peep2_count (count + 1),
 			      true, false);
-	  s = match_pattern_2 (s, top_pattern, subpos, x);
+	  s = match_pattern_2 (s, info, subpos, x);
 	  subpos_ptr = &subpos->next;
 	  count += 1;
 	}
@@ -4131,7 +4111,7 @@ match_pattern_1 (state *s, rtx top_patte
   else
     {
       /* Make the rtx itself.  */
-      s = match_pattern_2 (s, top_pattern, &root_pos, top_pattern);
+      s = match_pattern_2 (s, info, &root_pos, pattern);
 
       /* If the match is only valid when extra clobbers are added,
 	 make sure we're able to pass that information to the caller.  */
@@ -4152,7 +4132,7 @@ match_pattern_1 (state *s, rtx top_patte
    backtracking.  */
 
 static void
-match_pattern (state *s, rtx top_pattern, const char *c_test,
+match_pattern (state *s, md_rtx_info *info, rtx pattern, const char *c_test,
 	       acceptance_type acceptance)
 {
   if (merge_states_p)
@@ -4160,11 +4140,11 @@ match_pattern (state *s, rtx top_pattern
       state root;
       /* Add the decisions to a fresh state and then merge the full tree
 	 into the existing one.  */
-      match_pattern_1 (&root, top_pattern, c_test, acceptance);
+      match_pattern_1 (&root, info, pattern, c_test, acceptance);
       merge_into_state (s, &root);
     }
   else
-    match_pattern_1 (s, top_pattern, c_test, acceptance);
+    match_pattern_1 (s, info, pattern, c_test, acceptance);
 }
 
 /* Begin the output file.  */
@@ -5178,9 +5158,10 @@ print_subroutine_group (output_state *os
 /* Return the rtx pattern for the list of rtxes in a define_peephole2.  */
 
 static rtx
-get_peephole2_pattern (rtvec vec)
+get_peephole2_pattern (md_rtx_info *info)
 {
   int i, j;
+  rtvec vec = XVEC (info->def, 0);
   rtx pattern = rtx_alloc (SEQUENCE);
   XVEC (pattern, 0) = rtvec_alloc (GET_NUM_ELEM (vec));
   for (i = j = 0; i < GET_NUM_ELEM (vec); i++)
@@ -5195,7 +5176,7 @@ get_peephole2_pattern (rtvec vec)
     }
   XVECLEN (pattern, 0) = j;
   if (j == 0)
-    error_with_line (pattern_lineno, "empty define_peephole2");
+    error_at (info->loc, "empty define_peephole2");
   return pattern;
 }
 
@@ -5245,7 +5226,6 @@ remove_clobbers (acceptance_type *accept
 int
 main (int argc, char **argv)
 {
-  rtx desc;
   state insn_root, split_root, peephole2_root;
 
   progname = "genrecog";
@@ -5253,64 +5233,65 @@ main (int argc, char **argv)
   if (!init_rtx_reader_args (argc, argv))
     return (FATAL_EXIT_CODE);
 
-  next_insn_code = 0;
-
   write_header ();
 
   /* Read the machine description.  */
 
-  while (1)
+  md_rtx_info info;
+  while (read_md_rtx (&info))
     {
-      desc = read_md_rtx (&pattern_lineno, &next_insn_code);
-      if (desc == NULL)
-	break;
+      rtx def = info.def;
 
       acceptance_type acceptance;
       acceptance.partial_p = false;
-      acceptance.u.full.code = next_insn_code;
+      acceptance.u.full.code = info.index;
 
       rtx pattern;
-      switch (GET_CODE (desc))
+      switch (GET_CODE (def))
 	{
 	case DEFINE_INSN:
 	  {
 	    /* Match the instruction in the original .md form.  */
 	    acceptance.type = RECOG;
 	    acceptance.u.full.u.num_clobbers = 0;
-	    pattern = add_implicit_parallel (XVEC (desc, 1));
-	    validate_pattern (pattern, desc, NULL_RTX, 0);
-	    match_pattern (&insn_root, pattern, XSTR (desc, 2), acceptance);
+	    pattern = add_implicit_parallel (XVEC (def, 1));
+	    validate_pattern (pattern, &info, NULL_RTX, 0);
+	    match_pattern (&insn_root, &info, pattern,
+			   XSTR (def, 2), acceptance);
 
 	    /* If the pattern is a PARALLEL with trailing CLOBBERs,
 	       allow recog_for_combine to match without the clobbers.  */
 	    if (GET_CODE (pattern) == PARALLEL
 		&& remove_clobbers (&acceptance, &pattern))
-	      match_pattern (&insn_root, pattern, XSTR (desc, 2), acceptance);
+	      match_pattern (&insn_root, &info, pattern,
+			     XSTR (def, 2), acceptance);
 	    break;
 	  }
 
 	case DEFINE_SPLIT:
 	  acceptance.type = SPLIT;
-	  pattern = add_implicit_parallel (XVEC (desc, 0));
-	  validate_pattern (pattern, desc, NULL_RTX, 0);
-	  match_pattern (&split_root, pattern, XSTR (desc, 1), acceptance);
+	  pattern = add_implicit_parallel (XVEC (def, 0));
+	  validate_pattern (pattern, &info, NULL_RTX, 0);
+	  match_pattern (&split_root, &info, pattern,
+			 XSTR (def, 1), acceptance);
 
 	  /* Declare the gen_split routine that we'll call if the
 	     pattern matches.  The definition comes from insn-emit.c.  */
 	  printf ("extern rtx_insn *gen_split_%d (rtx_insn *, rtx *);\n",
-		  next_insn_code);
+		  info.index);
 	  break;
 
 	case DEFINE_PEEPHOLE2:
 	  acceptance.type = PEEPHOLE2;
-	  pattern = get_peephole2_pattern (XVEC (desc, 0));
-	  validate_pattern (pattern, desc, NULL_RTX, 0);
-	  match_pattern (&peephole2_root, pattern, XSTR (desc, 1), acceptance);
+	  pattern = get_peephole2_pattern (&info);
+	  validate_pattern (pattern, &info, NULL_RTX, 0);
+	  match_pattern (&peephole2_root, &info, pattern,
+			 XSTR (def, 1), acceptance);
 
 	  /* Declare the gen_peephole2 routine that we'll call if the
 	     pattern matches.  The definition comes from insn-emit.c.  */
 	  printf ("extern rtx_insn *gen_peephole2_%d (rtx_insn *, rtx *);\n",
-		  next_insn_code);
+		  info.index);
 	  break;
 
 	default:
Index: gcc/gentarget-def.c
===================================================================
--- gcc/gentarget-def.c	2015-07-12 14:18:07.691911409 +0100
+++ gcc/gentarget-def.c	2015-07-12 14:18:26.682112145 +0100
@@ -198,11 +198,27 @@ def_target_insn (const char *name, const
     printf ("CODE_FOR_%s\n", name);
 }
 
+/* Record the DEFINE_INSN or DEFINE_EXPAND described by INFO.  */
+
+static void
+add_insn (md_rtx_info *info)
+{
+  rtx def = info->def;
+  const char *name = XSTR (def, 0);
+  if (name[0] == 0 || name[0] == '*')
+    return;
+
+  hashval_t hash = htab_hash_string (name);
+  rtx *slot = insns->find_slot_with_hash (name, hash, INSERT);
+  if (*slot)
+    error_at (info->loc, "duplicate definition of '%s'", name);
+  else
+    *slot = def;
+}
+
 int
 main (int argc, char **argv)
 {
-  int insn_code_number = 0;
-
   progname = "gentarget-def";
 
   if (!init_rtx_reader_args (argc, argv))
@@ -212,30 +228,18 @@ main (int argc, char **argv)
   stubs = new hash_table <nofree_string_hash> (31);
   have_funcs = new hash_map <nofree_string_hash, const char *>;
 
-  while (1)
-    {
-      int line_no;
-      rtx desc = read_md_rtx (&line_no, &insn_code_number);
-      if (desc == NULL)
+  md_rtx_info info;
+  while (read_md_rtx (&info))
+    switch (GET_CODE (info.def))
+      {
+      case DEFINE_INSN:
+      case DEFINE_EXPAND:
+	add_insn (&info);
+	break;
+
+      default:
 	break;
-      if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
-	{
-	  const char *name = XSTR (desc, 0);
-	  if (name[0] != 0 && name[0] != '*')
-	    {
-	      hashval_t hash = htab_hash_string (name);
-	      rtx *slot = insns->find_slot_with_hash (name, hash, INSERT);
-	      if (*slot)
-		{
-		  message_with_line (line_no, "duplicate definition of '%s'",
-				     name);
-		  have_error = 1;
-		}
-	      else
-		*slot = desc;
-	    }
-	}
-    }
+      }
 
   printf ("/* Generated automatically by the program `gentarget-def'.  */\n");
   printf ("#ifndef GCC_INSN_TARGET_DEF_H\n");
