OSDN Git Service

gcc:
[pf3gnuchains/gcc-fork.git] / gcc / genpreds.c
index 41efc54..02379d6 100644 (file)
@@ -2,13 +2,14 @@
    - prototype declarations for operand predicates (tm-preds.h)
    - function definitions of operand predicates, if defined new-style
      (insn-preds.c)
    - prototype declarations for operand predicates (tm-preds.h)
    - function definitions of operand predicates, if defined new-style
      (insn-preds.c)
-   Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
+   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
 
 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)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GCC is distributed in the hope that it will be useful,
 any later version.
 
 GCC is distributed in the hope that it will be useful,
@@ -17,9 +18,8 @@ MERCHANTABILITY or 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
 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, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "bconfig.h"
 #include "system.h"
 
 #include "bconfig.h"
 #include "system.h"
@@ -28,6 +28,7 @@ Boston, MA 02110-1301, USA.  */
 #include "rtl.h"
 #include "errors.h"
 #include "obstack.h"
 #include "rtl.h"
 #include "errors.h"
 #include "obstack.h"
+#include "read-md.h"
 #include "gensupport.h"
 
 /* Given a predicate expression EXP, from form NAME at line LINENO,
 #include "gensupport.h"
 
 /* Given a predicate expression EXP, from form NAME at line LINENO,
@@ -66,9 +67,8 @@ validate_exp (rtx exp, const char *name, int lineno)
          {
            if (!ISDIGIT (*p) && !ISLOWER (*p))
              {
          {
            if (!ISDIGIT (*p) && !ISLOWER (*p))
              {
-               message_with_line (lineno, "%s: invalid character in path "
-                                  "string '%s'", name, XSTR (exp, 1));
-               have_error = 1;
+               error_with_line (lineno, "%s: invalid character in path "
+                                "string '%s'", name, XSTR (exp, 1));
                return true;
              }
          }
                return true;
              }
          }
@@ -81,10 +81,9 @@ validate_exp (rtx exp, const char *name, int lineno)
       return false;
 
     default:
       return false;
 
     default:
-      message_with_line (lineno,
-                        "%s: cannot use '%s' in a predicate expression",
-                        name, GET_RTX_NAME (GET_CODE (exp)));
-      have_error = 1;
+      error_with_line (lineno,
+                      "%s: cannot use '%s' in a predicate expression",
+                      name, GET_RTX_NAME (GET_CODE (exp)));
       return true;
     }
 }
       return true;
     }
 }
@@ -102,7 +101,7 @@ process_define_predicate (rtx defn, int lineno)
   for (p = XSTR (defn, 0) + 1; *p; p++)
     if (!ISALNUM (*p) && *p != '_')
       goto bad_name;
   for (p = XSTR (defn, 0) + 1; *p; p++)
     if (!ISALNUM (*p) && *p != '_')
       goto bad_name;
-  
+
   if (validate_exp (XEXP (defn, 1), XSTR (defn, 0), lineno))
     return;
 
   if (validate_exp (XEXP (defn, 1), XSTR (defn, 0), lineno))
     return;
 
@@ -118,10 +117,9 @@ process_define_predicate (rtx defn, int lineno)
   return;
 
  bad_name:
   return;
 
  bad_name:
-  message_with_line (lineno,
-                    "%s: predicate name must be a valid C function name",
-                    XSTR (defn, 0));
-  have_error = 1;
+  error_with_line (lineno,
+                  "%s: predicate name must be a valid C function name",
+                  XSTR (defn, 0));
   return;
 }
 
   return;
 }
 
@@ -153,7 +151,7 @@ process_define_predicate (rtx defn, int lineno)
    The only wart is that there's no way to insist on a { } string in
    an RTL template, so we have to handle "" strings.  */
 
    The only wart is that there's no way to insist on a { } string in
    an RTL template, so we have to handle "" strings.  */
 
-   
+
 static void
 write_predicate_subfunction (struct pred_data *p)
 {
 static void
 write_predicate_subfunction (struct pred_data *p)
 {
@@ -183,7 +181,7 @@ write_predicate_subfunction (struct pred_data *p)
   printf ("static inline int\n"
          "%s_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)\n",
          p->name);
   printf ("static inline int\n"
          "%s_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)\n",
          p->name);
-  print_rtx_ptr_loc (p->c_block);
+  print_md_ptr_loc (p->c_block);
   if (p->c_block[0] == '{')
     fputs (p->c_block, stdout);
   else
   if (p->c_block[0] == '{')
     fputs (p->c_block, stdout);
   else
@@ -234,7 +232,7 @@ needs_variable (rtx exp, const char *var)
        if (q != p && (ISALNUM (q[-1]) || q[-1] == '_'))
          return false;
        q += strlen (var);
        if (q != p && (ISALNUM (q[-1]) || q[-1] == '_'))
          return false;
        q += strlen (var);
-       if (ISALNUM (q[0] || q[0] == '_'))
+       if (ISALNUM (q[0]) || q[0] == '_')
          return false;
       }
       return true;
          return false;
       }
       return true;
@@ -290,7 +288,7 @@ mark_mode_tests (rtx exp)
       NO_MODE_TEST (exp) = (NO_MODE_TEST (XEXP (exp, 0))
                            && NO_MODE_TEST (XEXP (exp, 1)));
       break;
       NO_MODE_TEST (exp) = (NO_MODE_TEST (XEXP (exp, 0))
                            && NO_MODE_TEST (XEXP (exp, 1)));
       break;
-      
+
     case IOR:
       mark_mode_tests (XEXP (exp, 0));
       mark_mode_tests (XEXP (exp, 1));
     case IOR:
       mark_mode_tests (XEXP (exp, 0));
       mark_mode_tests (XEXP (exp, 1));
@@ -373,7 +371,7 @@ add_mode_tests (struct pred_data *p)
        case AND:
          /* The switch code generation in write_predicate_stmts prefers
             rtx code tests to be at the top of the expression tree.  So
        case AND:
          /* The switch code generation in write_predicate_stmts prefers
             rtx code tests to be at the top of the expression tree.  So
-            push this AND down into the second operand of an exisiting
+            push this AND down into the second operand of an existing
             AND expression.  */
          if (generate_switch_p (XEXP (subexp, 0)))
            pos = &XEXP (subexp, 1);
             AND expression.  */
          if (generate_switch_p (XEXP (subexp, 0)))
            pos = &XEXP (subexp, 1);
@@ -383,23 +381,23 @@ add_mode_tests (struct pred_data *p)
          {
            int test0 = NO_MODE_TEST (XEXP (subexp, 0));
            int test1 = NO_MODE_TEST (XEXP (subexp, 1));
          {
            int test0 = NO_MODE_TEST (XEXP (subexp, 0));
            int test1 = NO_MODE_TEST (XEXP (subexp, 1));
-           
+
            gcc_assert (test0 || test1);
            gcc_assert (test0 || test1);
-           
+
            if (test0 && test1)
              goto break_loop;
            pos = test0 ? &XEXP (subexp, 0) : &XEXP (subexp, 1);
          }
          break;
            if (test0 && test1)
              goto break_loop;
            pos = test0 ? &XEXP (subexp, 0) : &XEXP (subexp, 1);
          }
          break;
-         
+
        case IF_THEN_ELSE:
          {
            int test0 = NO_MODE_TEST (XEXP (subexp, 0));
            int test1 = NO_MODE_TEST (XEXP (subexp, 1));
            int test2 = NO_MODE_TEST (XEXP (subexp, 2));
        case IF_THEN_ELSE:
          {
            int test0 = NO_MODE_TEST (XEXP (subexp, 0));
            int test1 = NO_MODE_TEST (XEXP (subexp, 1));
            int test2 = NO_MODE_TEST (XEXP (subexp, 2));
-           
+
            gcc_assert ((test0 && test1) || test2);
            gcc_assert ((test0 && test1) || test2);
-           
+
            if (test0 && test1 && test2)
              goto break_loop;
            if (test0 && test1)
            if (test0 && test1 && test2)
              goto break_loop;
            if (test0 && test1)
@@ -411,7 +409,7 @@ add_mode_tests (struct pred_data *p)
              pos = &XEXP (subexp, 2);
          }
          break;
              pos = &XEXP (subexp, 2);
          }
          break;
-         
+
        default:
          goto break_loop;
        }
        default:
          goto break_loop;
        }
@@ -473,7 +471,7 @@ write_match_code (const char *path, const char *codes)
          putchar (TOUPPER (*code));
          code++;
        }
          putchar (TOUPPER (*code));
          code++;
        }
-      
+
       if (*codes == ',')
        fputs (" || ", stdout);
     }
       if (*codes == ',')
        fputs (" || ", stdout);
     }
@@ -493,7 +491,7 @@ write_predicate_expr (rtx exp)
       write_predicate_expr (XEXP (exp, 1));
       putchar (')');
       break;
       write_predicate_expr (XEXP (exp, 1));
       putchar (')');
       break;
-  
+
     case IOR:
       putchar ('(');
       write_predicate_expr (XEXP (exp, 0));
     case IOR:
       putchar ('(');
       write_predicate_expr (XEXP (exp, 0));
@@ -543,8 +541,8 @@ write_predicate_expr (rtx exp)
 static void
 write_match_code_switch (rtx exp)
 {
 static void
 write_match_code_switch (rtx exp)
 {
-  const char *codes = (const char *) XEXP (exp, 0);
-  const char *path = (const char *) XEXP (exp, 1);
+  const char *codes = XSTR (exp, 0);
+  const char *path = XSTR (exp, 1);
   const char *code;
 
   fputs ("  switch (GET_CODE (", stdout);
   const char *code;
 
   fputs ("  switch (GET_CODE (", stdout);
@@ -563,7 +561,7 @@ write_match_code_switch (rtx exp)
     }
 }
 
     }
 }
 
-/* Given a predictate expression EXP, write out a sequence of stmts
+/* Given a predicate expression EXP, write out a sequence of stmts
    to evaluate it.  This is similar to write_predicate_expr but can
    generate efficient switch statements.  */
 
    to evaluate it.  This is similar to write_predicate_expr but can
    generate efficient switch statements.  */
 
@@ -607,6 +605,7 @@ write_predicate_stmts (rtx exp)
                "    }");
          exp = XEXP (exp, 1);
        }
                "    }");
          exp = XEXP (exp, 1);
        }
+      break;
 
     case NOT:
       if (generate_switch_p (XEXP (exp, 0)))
 
     case NOT:
       if (generate_switch_p (XEXP (exp, 0)))
@@ -689,8 +688,11 @@ static struct constraint_data **last_constraint_ptr = &first_constraint;
   for (iter_ = first_constraint; iter_; iter_ = iter_->next_textual)
 
 /* These letters, and all names beginning with them, are reserved for
   for (iter_ = first_constraint; iter_; iter_ = iter_->next_textual)
 
 /* These letters, and all names beginning with them, are reserved for
-   generic constraints.  */
-static const char generic_constraint_letters[] = "EFVXgimnoprs";
+   generic constraints.
+   The 'm' constraint is not mentioned here since that constraint
+   letter can be overridden by the back end by defining the
+   TARGET_MEM_CONSTRAINT macro.  */
+static const char generic_constraint_letters[] = "EFVXginoprs";
 
 /* Machine-independent code expects that constraints with these
    (initial) letters will allow only (a subset of all) CONST_INTs.  */
 
 /* Machine-independent code expects that constraints with these
    (initial) letters will allow only (a subset of all) CONST_INTs.  */
@@ -728,7 +730,7 @@ mangle (const char *name)
       }
 
   obstack_1grow (rtl_obstack, '\0');
       }
 
   obstack_1grow (rtl_obstack, '\0');
-  return obstack_finish (rtl_obstack);
+  return XOBFINISH (rtl_obstack, const char *);
 }
 
 /* Add one constraint, of any sort, to the tables.  NAME is its name;
 }
 
 /* Add one constraint, of any sort, to the tables.  NAME is its name;
@@ -760,12 +762,11 @@ add_constraint (const char *name, const char *regclass,
   if (!ISALPHA (name[0]) && name[0] != '_')
     {
       if (name[1] == '\0')
   if (!ISALPHA (name[0]) && name[0] != '_')
     {
       if (name[1] == '\0')
-       message_with_line (lineno, "constraint name '%s' is not "
-                          "a letter or underscore", name);
+       error_with_line (lineno, "constraint name '%s' is not "
+                        "a letter or underscore", name);
       else
       else
-       message_with_line (lineno, "constraint name '%s' does not begin "
-                          "with a letter or underscore", name);
-      have_error = 1;
+       error_with_line (lineno, "constraint name '%s' does not begin "
+                        "with a letter or underscore", name);
       return;
     }
   for (p = name; *p; p++)
       return;
     }
   for (p = name; *p; p++)
@@ -775,11 +776,10 @@ add_constraint (const char *name, const char *regclass,
          need_mangled_name = true;
        else
          {
          need_mangled_name = true;
        else
          {
-           message_with_line (lineno,
-                              "constraint name '%s' must be composed of "
-                              "letters, digits, underscores, and "
-                              "angle brackets", name);
-           have_error = 1;
+           error_with_line (lineno,
+                            "constraint name '%s' must be composed of "
+                            "letters, digits, underscores, and "
+                            "angle brackets", name);
            return;
          }
       }
            return;
          }
       }
@@ -787,17 +787,16 @@ add_constraint (const char *name, const char *regclass,
   if (strchr (generic_constraint_letters, name[0]))
     {
       if (name[1] == '\0')
   if (strchr (generic_constraint_letters, name[0]))
     {
       if (name[1] == '\0')
-       message_with_line (lineno, "constraint letter '%s' cannot be "
-                          "redefined by the machine description", name);
+       error_with_line (lineno, "constraint letter '%s' cannot be "
+                        "redefined by the machine description", name);
       else
       else
-       message_with_line (lineno, "constraint name '%s' cannot be defined by "
-                          "the machine description, as it begins with '%c'",
-                          name, name[0]);
-      have_error = 1;
+       error_with_line (lineno, "constraint name '%s' cannot be defined by "
+                        "the machine description, as it begins with '%c'",
+                        name, name[0]);
       return;
     }
 
       return;
     }
 
-  
+
   namelen = strlen (name);
   slot = &constraints_by_letter_table[(unsigned int)name[0]];
   for (iter = slot; *iter; iter = &(*iter)->next_this_letter)
   namelen = strlen (name);
   slot = &constraints_by_letter_table[(unsigned int)name[0]];
   for (iter = slot; *iter; iter = &(*iter)->next_this_letter)
@@ -812,25 +811,22 @@ add_constraint (const char *name, const char *regclass,
 
       if (!strcmp ((*iter)->name, name))
        {
 
       if (!strcmp ((*iter)->name, name))
        {
-         message_with_line (lineno, "redefinition of constraint '%s'", name);
+         error_with_line (lineno, "redefinition of constraint '%s'", name);
          message_with_line ((*iter)->lineno, "previous definition is here");
          message_with_line ((*iter)->lineno, "previous definition is here");
-         have_error = 1;
          return;
        }
       else if (!strncmp ((*iter)->name, name, (*iter)->namelen))
        {
          return;
        }
       else if (!strncmp ((*iter)->name, name, (*iter)->namelen))
        {
-         message_with_line (lineno, "defining constraint '%s' here", name);
+         error_with_line (lineno, "defining constraint '%s' here", name);
          message_with_line ((*iter)->lineno, "renders constraint '%s' "
                             "(defined here) a prefix", (*iter)->name);
          message_with_line ((*iter)->lineno, "renders constraint '%s' "
                             "(defined here) a prefix", (*iter)->name);
-         have_error = 1;
          return;
        }
       else if (!strncmp ((*iter)->name, name, namelen))
        {
          return;
        }
       else if (!strncmp ((*iter)->name, name, namelen))
        {
-         message_with_line (lineno, "constraint '%s' is a prefix", name);
+         error_with_line (lineno, "constraint '%s' is a prefix", name);
          message_with_line ((*iter)->lineno, "of constraint '%s' "
                             "(defined here)", (*iter)->name);
          message_with_line ((*iter)->lineno, "of constraint '%s' "
                             "(defined here)", (*iter)->name);
-         have_error = 1;
          return;
        }
     }
          return;
        }
     }
@@ -851,53 +847,42 @@ add_constraint (const char *name, const char *regclass,
                     GET_RTX_NAME (appropriate_code)))
        {
          if (name[1] == '\0')
                     GET_RTX_NAME (appropriate_code)))
        {
          if (name[1] == '\0')
-           message_with_line (lineno, "constraint letter '%c' is reserved "
-                              "for %s constraints",
-                              name[0], GET_RTX_NAME (appropriate_code));
+           error_with_line (lineno, "constraint letter '%c' is reserved "
+                            "for %s constraints",
+                            name[0], GET_RTX_NAME (appropriate_code));
          else
          else
-           message_with_line (lineno, "constraint names beginning with '%c' "
-                              "(%s) are reserved for %s constraints",
-                              name[0], name, 
-                              GET_RTX_NAME (appropriate_code));
-
-         have_error = 1;
+           error_with_line (lineno, "constraint names beginning with '%c' "
+                            "(%s) are reserved for %s constraints",
+                            name[0], name, GET_RTX_NAME (appropriate_code));
          return;
        }
 
       if (is_memory)
        {
          if (name[1] == '\0')
          return;
        }
 
       if (is_memory)
        {
          if (name[1] == '\0')
-           message_with_line (lineno, "constraint letter '%c' cannot be a "
-                              "memory constraint", name[0]);
+           error_with_line (lineno, "constraint letter '%c' cannot be a "
+                            "memory constraint", name[0]);
          else
          else
-           message_with_line (lineno, "constraint name '%s' begins with '%c', "
-                              "and therefore cannot be a memory constraint",
-                              name, name[0]);
-
-         have_error = 1;
+           error_with_line (lineno, "constraint name '%s' begins with '%c', "
+                            "and therefore cannot be a memory constraint",
+                            name, name[0]);
          return;
        }
       else if (is_address)
        {
          if (name[1] == '\0')
          return;
        }
       else if (is_address)
        {
          if (name[1] == '\0')
-           message_with_line (lineno, "constraint letter '%c' cannot be a "
-                              "memory constraint", name[0]);
+           error_with_line (lineno, "constraint letter '%c' cannot be a "
+                            "memory constraint", name[0]);
          else
          else
-           message_with_line (lineno, "constraint name '%s' begins with '%c', "
-                              "and therefore cannot be a memory constraint",
-                              name, name[0]);
-
-         have_error = 1;
+           error_with_line (lineno, "constraint name '%s' begins with '%c', "
+                            "and therefore cannot be a memory constraint",
+                            name, name[0]);
          return;
        }
          return;
        }
-
-      /* Remove the redundant (and (match_code "const_(int|double)")
-        from the expression.  */
-      exp = XEXP (exp, 1);
     }
 
     }
 
-  
-  c = obstack_alloc (rtl_obstack, sizeof (struct constraint_data));
+
+  c = XOBNEW (rtl_obstack, struct constraint_data);
   c->name = name;
   c->c_name = need_mangled_name ? mangle (name) : name;
   c->lineno = lineno;
   c->name = name;
   c->c_name = need_mangled_name ? mangle (name) : name;
   c->lineno = lineno;
@@ -954,12 +939,13 @@ write_enum_constraint_num (void)
 {
   struct constraint_data *c;
 
 {
   struct constraint_data *c;
 
+  fputs ("#define CONSTRAINT_NUM_DEFINED_P 1\n", stdout);
   fputs ("enum constraint_num\n"
         "{\n"
         "  CONSTRAINT__UNKNOWN = 0", stdout);
   FOR_ALL_CONSTRAINTS (c)
     printf (",\n  CONSTRAINT_%s", c->c_name);
   fputs ("enum constraint_num\n"
         "{\n"
         "  CONSTRAINT__UNKNOWN = 0", stdout);
   FOR_ALL_CONSTRAINTS (c)
     printf (",\n  CONSTRAINT_%s", c->c_name);
-  puts ("\n};\n");
+  puts (",\n  CONSTRAINT__LIMIT\n};\n");
 }
 
 /* Write out a function which looks at a string and determines what
 }
 
 /* Write out a function which looks at a string and determines what
@@ -1003,33 +989,51 @@ write_lookup_constraint (void)
        "}\n");
 }
 
        "}\n");
 }
 
-/* Write out the function which computes constraint name lengths from
-   their enumerators. */
+/* Write out a function which looks at a string and determines what
+   the constraint name length is.  */
 static void
 write_insn_constraint_len (void)
 {
 static void
 write_insn_constraint_len (void)
 {
-  struct constraint_data *c;
-
-  if (constraint_max_namelen == 1)
-    return;
+  unsigned int i;
 
 
-  puts ("size_t\n"
-       "insn_constraint_len (enum constraint_num c)\n"
+  puts ("static inline size_t\n"
+       "insn_constraint_len (char fc, const char *str ATTRIBUTE_UNUSED)\n"
        "{\n"
        "{\n"
-       "  switch (c)\n"
+       "  switch (fc)\n"
        "    {");
 
        "    {");
 
-  FOR_ALL_CONSTRAINTS (c)
-    if (c->namelen > 1)
-      printf ("    case CONSTRAINT_%s: return %lu;\n", c->c_name,
-             (unsigned long int) c->namelen);
+  for (i = 0; i < ARRAY_SIZE(constraints_by_letter_table); i++)
+    {
+      struct constraint_data *c = constraints_by_letter_table[i];
+
+      if (!c
+         || c->namelen == 1)
+       continue;
+
+      /* Constraints with multiple characters should have the same
+        length.  */
+      {
+       struct constraint_data *c2 = c->next_this_letter;
+       size_t len = c->namelen;
+       while (c2)
+         {
+           if (c2->namelen != len)
+             error ("Multi-letter constraints with first letter '%c' "
+                    "should have same length", i);
+           c2 = c2->next_this_letter;
+         }
+      }
+
+      printf ("    case '%c': return %lu;\n",
+             i, (unsigned long int) c->namelen);
+    }
 
   puts ("    default: break;\n"
        "    }\n"
        "  return 1;\n"
        "}\n");
 }
 
   puts ("    default: break;\n"
        "    }\n"
        "  return 1;\n"
        "}\n");
 }
-  
+
 /* Write out the function which computes the register class corresponding
    to a register constraint.  */
 static void
 /* Write out the function which computes the register class corresponding
    to a register constraint.  */
 static void
@@ -1077,12 +1081,15 @@ write_tm_constrs_h (void)
        bool needs_rval = needs_variable (c->exp, "rval");
        bool needs_mode = (needs_variable (c->exp, "mode")
                           || needs_hval || needs_lval || needs_rval);
        bool needs_rval = needs_variable (c->exp, "rval");
        bool needs_mode = (needs_variable (c->exp, "mode")
                           || needs_hval || needs_lval || needs_rval);
+       bool needs_op = (needs_variable (c->exp, "op")
+                        || needs_ival || needs_mode);
 
        printf ("static inline bool\n"
 
        printf ("static inline bool\n"
-               "satisfies_constraint_%s (rtx op)\n"
-               "{\n", c->c_name);
+               "satisfies_constraint_%s (rtx %s)\n"
+               "{\n", c->c_name,
+               needs_op ? "op" : "ARG_UNUSED (op)");
        if (needs_mode)
        if (needs_mode)
-         puts ("enum machine_mode mode = GET_MODE (op);");
+         puts ("  enum machine_mode mode = GET_MODE (op);");
        if (needs_ival)
          puts ("  HOST_WIDE_INT ival = 0;");
        if (needs_hval)
        if (needs_ival)
          puts ("  HOST_WIDE_INT ival = 0;");
        if (needs_hval)
@@ -1093,7 +1100,7 @@ write_tm_constrs_h (void)
          puts ("  const REAL_VALUE_TYPE *rval = 0;");
 
        if (needs_ival)
          puts ("  const REAL_VALUE_TYPE *rval = 0;");
 
        if (needs_ival)
-         puts ("  if (GET_CODE (op) == CONST_INT)\n"
+         puts ("  if (CONST_INT_P (op))\n"
                "    ival = INTVAL (op);");
        if (needs_hval)
          puts ("  if (GET_CODE (op) == CONST_DOUBLE && mode == VOIDmode)"
                "    ival = INTVAL (op);");
        if (needs_hval)
          puts ("  if (GET_CODE (op) == CONST_DOUBLE && mode == VOIDmode)"
@@ -1156,7 +1163,10 @@ write_insn_const_int_ok_for_constraint (void)
     if (c->is_const_int)
       {
        printf ("    case CONSTRAINT_%s:\n      return ", c->c_name);
     if (c->is_const_int)
       {
        printf ("    case CONSTRAINT_%s:\n      return ", c->c_name);
-       write_predicate_expr (c->exp);
+       /* c->exp is guaranteed to be (and (match_code "const_int") (...));
+          we know at this point that we have a const_int, so we need not
+          bother with that part of the test.  */
+       write_predicate_expr (XEXP (c->exp, 1));
        fputs (";\n\n", stdout);
       }
 
        fputs (";\n\n", stdout);
       }
 
@@ -1244,18 +1254,24 @@ write_tm_preds_h (void)
            "extern bool constraint_satisfied_p (rtx, enum constraint_num);\n");
 
       if (constraint_max_namelen > 1)
            "extern bool constraint_satisfied_p (rtx, enum constraint_num);\n");
 
       if (constraint_max_namelen > 1)
-       puts ("extern size_t insn_constraint_len (enum constraint_num);\n"
-             "#define CONSTRAINT_LEN(c_,s_) "
-             "insn_constraint_len (lookup_constraint (s_))\n");
+        {
+         write_insn_constraint_len ();
+         puts ("#define CONSTRAINT_LEN(c_,s_) "
+               "insn_constraint_len (c_,s_)\n");
+       }
       else
        puts ("#define CONSTRAINT_LEN(c_,s_) 1\n");
       if (have_register_constraints)
        puts ("extern enum reg_class regclass_for_constraint "
              "(enum constraint_num);\n"
              "#define REG_CLASS_FROM_CONSTRAINT(c_,s_) \\\n"
       else
        puts ("#define CONSTRAINT_LEN(c_,s_) 1\n");
       if (have_register_constraints)
        puts ("extern enum reg_class regclass_for_constraint "
              "(enum constraint_num);\n"
              "#define REG_CLASS_FROM_CONSTRAINT(c_,s_) \\\n"
-             "    regclass_for_constraint (lookup_constraint (s_))\n");
+             "    regclass_for_constraint (lookup_constraint (s_))\n"
+             "#define REG_CLASS_FOR_CONSTRAINT(x_) \\\n"
+             "    regclass_for_constraint (x_)\n");
       else
       else
-       puts ("#define REG_CLASS_FROM_CONSTRAINT(c_,s_) NO_REGS");
+       puts ("#define REG_CLASS_FROM_CONSTRAINT(c_,s_) NO_REGS\n"
+             "#define REG_CLASS_FOR_CONSTRAINT(x_) \\\n"
+             "    NO_REGS\n");
       if (have_const_int_constraints)
        puts ("extern bool insn_const_int_ok_for_constraint "
              "(HOST_WIDE_INT, enum constraint_num);\n"
       if (have_const_int_constraints)
        puts ("extern bool insn_const_int_ok_for_constraint "
              "(HOST_WIDE_INT, enum constraint_num);\n"
@@ -1289,7 +1305,7 @@ write_tm_preds_h (void)
   puts ("#endif /* tm-preds.h */");
 }
 
   puts ("#endif /* tm-preds.h */");
 }
 
-/* Write insn-preds.c.  
+/* Write insn-preds.c.
    N.B. the list of headers to include was copied from genrecog; it
    may not be ideal.
 
    N.B. the list of headers to include was copied from genrecog; it
    may not be ideal.
 
@@ -1317,11 +1333,11 @@ write_insn_preds_c (void)
 #include \"function.h\"\n\
 #include \"insn-config.h\"\n\
 #include \"recog.h\"\n\
 #include \"function.h\"\n\
 #include \"insn-config.h\"\n\
 #include \"recog.h\"\n\
-#include \"real.h\"\n\
 #include \"output.h\"\n\
 #include \"flags.h\"\n\
 #include \"hard-reg-set.h\"\n\
 #include \"resource.h\"\n\
 #include \"output.h\"\n\
 #include \"flags.h\"\n\
 #include \"hard-reg-set.h\"\n\
 #include \"resource.h\"\n\
+#include \"diagnostic-core.h\"\n\
 #include \"toplev.h\"\n\
 #include \"reload.h\"\n\
 #include \"regs.h\"\n\
 #include \"toplev.h\"\n\
 #include \"reload.h\"\n\
 #include \"regs.h\"\n\
@@ -1333,11 +1349,9 @@ write_insn_preds_c (void)
   if (constraint_max_namelen > 0)
     {
       write_lookup_constraint ();
   if (constraint_max_namelen > 0)
     {
       write_lookup_constraint ();
-      write_regclass_for_constraint ();
+      if (have_register_constraints)
+       write_regclass_for_constraint ();
       write_constraint_satisfied_p ();
       write_constraint_satisfied_p ();
-      
-      if (constraint_max_namelen > 1)
-       write_insn_constraint_len ();
 
       if (have_const_int_constraints)
        write_insn_const_int_ok_for_constraint ();
 
       if (have_const_int_constraints)
        write_insn_const_int_ok_for_constraint ();
@@ -1380,7 +1394,7 @@ main (int argc, char **argv)
   progname = argv[0];
   if (argc <= 1)
     fatal ("no input file name");
   progname = argv[0];
   if (argc <= 1)
     fatal ("no input file name");
-  if (init_md_reader_args_cb (argc, argv, parse_option) != SUCCESS_EXIT_CODE)
+  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)
     return FATAL_EXIT_CODE;
 
   while ((defn = read_md_rtx (&pattern_lineno, &next_insn_code)) != 0)