OSDN Git Service

2002-04-12 Eric Norum <eric.norum@usask.ca>
[pf3gnuchains/gcc-fork.git] / gcc / genopinit.c
index 985be8f..384a066 100644 (file)
@@ -1,39 +1,31 @@
 /* Generate code to initialize optabs from machine description.
-   Copyright (C) 1993, 94-97, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998,
+   1999, 2000 Free Software Foundation, Inc.
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
 
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of 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
-along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
 
 
 #include "hconfig.h"
 #include "system.h"
 #include "rtl.h"
-#include "obstack.h"
+#include "errors.h"
+#include "gensupport.h"
 
-static struct obstack obstack;
-struct obstack *rtl_obstack = &obstack;
-
-#define obstack_chunk_alloc xmalloc
-#define obstack_chunk_free free
-
-char *xmalloc PROTO((unsigned));
-static void fatal PVPROTO ((char *, ...))
-  ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
-void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
 
 /* Many parts of GCC use arrays that are indexed by machine mode and
    contain the insn codes for pattern in the MD file that perform a given
@@ -46,96 +38,112 @@ void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN;
 
    This array contains a list of optabs that need to be initialized.  Within
    each string, the name of the pattern to be matched against is delimited
-   with %( and %).  In the string, %a and %b are used to match a short mode
+   with $( and $).  In the string, $a and $b are used to match a short mode
    name (the part of the mode name not including `mode' and converted to
    lower-case).  When writing out the initializer, the entire string is
-   used.  %A and %B are replaced with the full name of the mode; %a and %b
+   used.  $A and $B are replaced with the full name of the mode; $a and $b
    are replaced with the short form of the name, as above.
 
-   If %N is present in the pattern, it means the two modes must be consecutive
-   widths in the same mode class (e.g, QImode and HImode).  %I means that
-   only integer modes should be considered for the next mode, and %F means
-   that only float modes should be considered.
+   If $N is present in the pattern, it means the two modes must be consecutive
+   widths in the same mode class (e.g, QImode and HImode).  $I means that
+   only full integer modes should be considered for the next mode, and $F
+   means that only float modes should be considered.
+   $P means that both full and partial integer modes should be considered.
+
+   $V means to emit 'v' if the first mode is a MODE_FLOAT mode.
 
    For some optabs, we store the operation by RTL codes.  These are only
-   used for comparisons.  In that case, %c and %C are the lower-case and
+   used for comparisons.  In that case, $c and $C are the lower-case and
    upper-case forms of the comparison, respectively.  */
 
-/* The reason we use \% is to avoid sequences of the form %-capletter-%
-   which SCCS treats as magic.  This gets warnings which you should ignore.  */
-
-char *optabs[] =
-{ "extendtab[(int) %B][(int) %A][0] = CODE_FOR_%(extend%a\%b2%)",
-  "extendtab[(int) %B][(int) %A][1] = CODE_FOR_%(zero_extend%a\%b2%)",
-  "fixtab[(int) %A][(int) %B][0] = CODE_FOR_%(fix%F\%a%I\%b2%)",
-  "fixtab[(int) %A][(int) %B][1] = CODE_FOR_%(fixuns%F\%a%b2%)",
-  "fixtrunctab[(int) %A][(int) %B][0] = CODE_FOR_%(fix_trunc%F\%a%I\%b2%)",
-  "fixtrunctab[(int) %A][(int) %B][1] = CODE_FOR_%(fixuns_trunc%F\%a%I\%b2%)",
-  "floattab[(int) %B][(int) %A][0] = CODE_FOR_%(float%I\%a%F\%b2%)",
-  "floattab[(int) %B][(int) %A][1] = CODE_FOR_%(floatuns%I\%a%F\%b2%)",
-  "add_optab->handlers[(int) %A].insn_code = CODE_FOR_%(add%a3%)",
-  "sub_optab->handlers[(int) %A].insn_code = CODE_FOR_%(sub%a3%)",
-  "smul_optab->handlers[(int) %A].insn_code = CODE_FOR_%(mul%a3%)",
-  "umul_highpart_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umul%a3_highpart%)",
-  "smul_highpart_optab->handlers[(int) %A].insn_code = CODE_FOR_%(smul%a3_highpart%)",
-  "smul_widen_optab->handlers[(int) %B].insn_code = CODE_FOR_%(mul%a%b3%)%N",
-  "umul_widen_optab->handlers[(int) %B].insn_code = CODE_FOR_%(umul%a%b3%)%N",
-  "sdiv_optab->handlers[(int) %A].insn_code = CODE_FOR_%(div%I\%a3%)",
-  "udiv_optab->handlers[(int) %A].insn_code = CODE_FOR_%(udiv%I\%a3%)",
-  "sdivmod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(divmod%a4%)",
-  "udivmod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(udivmod%a4%)",
-  "smod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(mod%a3%)",
-  "umod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umod%a3%)",
-  "flodiv_optab->handlers[(int) %A].insn_code = CODE_FOR_%(div%F\%a3%)",
-  "ftrunc_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ftrunc%F\%a2%)",
-  "and_optab->handlers[(int) %A].insn_code = CODE_FOR_%(and%a3%)",
-  "ior_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ior%a3%)",
-  "xor_optab->handlers[(int) %A].insn_code = CODE_FOR_%(xor%a3%)",
-  "ashl_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ashl%a3%)",
-  "ashr_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ashr%a3%)",
-  "lshr_optab->handlers[(int) %A].insn_code = CODE_FOR_%(lshr%a3%)",
-  "rotl_optab->handlers[(int) %A].insn_code = CODE_FOR_%(rotl%a3%)",
-  "rotr_optab->handlers[(int) %A].insn_code = CODE_FOR_%(rotr%a3%)",
-  "smin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(smin%I\%a3%)",
-  "smin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(min%F\%a3%)",
-  "smax_optab->handlers[(int) %A].insn_code = CODE_FOR_%(smax%I\%a3%)",
-  "smax_optab->handlers[(int) %A].insn_code = CODE_FOR_%(max%F\%a3%)",
-  "umin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umin%I\%a3%)",
-  "umax_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umax%I\%a3%)",
-  "neg_optab->handlers[(int) %A].insn_code = CODE_FOR_%(neg%a2%)",
-  "abs_optab->handlers[(int) %A].insn_code = CODE_FOR_%(abs%a2%)",
-  "sqrt_optab->handlers[(int) %A].insn_code = CODE_FOR_%(sqrt%a2%)",
-  "sin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(sin%a2%)",
-  "cos_optab->handlers[(int) %A].insn_code = CODE_FOR_%(cos%a2%)",
-  "strlen_optab->handlers[(int) %A].insn_code = CODE_FOR_%(strlen%a%)",
-  "one_cmpl_optab->handlers[(int) %A].insn_code = CODE_FOR_%(one_cmpl%a2%)",
-  "ffs_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ffs%a2%)",
-  "mov_optab->handlers[(int) %A].insn_code = CODE_FOR_%(mov%a%)",
-  "movstrict_optab->handlers[(int) %A].insn_code = CODE_FOR_%(movstrict%a%)",
-  "cmp_optab->handlers[(int) %A].insn_code = CODE_FOR_%(cmp%a%)",
-  "tst_optab->handlers[(int) %A].insn_code = CODE_FOR_%(tst%a%)",
-  "bcc_gen_fctn[(int) %C] = gen_%(b%c%)",
-  "setcc_gen_code[(int) %C] = CODE_FOR_%(s%c%)",
-  "movcc_gen_code[(int) %A] = CODE_FOR_%(mov%acc%)",
-  "reload_in_optab[(int) %A] = CODE_FOR_%(reload_in%a%)",
-  "reload_out_optab[(int) %A] = CODE_FOR_%(reload_out%a%)",
-  "movstr_optab[(int) %A] = CODE_FOR_%(movstr%a%)",
-  "clrstr_optab[(int) %A] = CODE_FOR_%(clrstr%a%)" };
-
-/* Allow linking with print-rtl.c.  */
-char **insn_name_ptr;
-
-static void gen_insn PROTO((rtx));
+static const char * const optabs[] =
+{ "extendtab[$B][$A][0] = CODE_FOR_$(extend$a$b2$)",
+  "extendtab[$B][$A][1] = CODE_FOR_$(zero_extend$a$b2$)",
+  "fixtab[$A][$B][0] = CODE_FOR_$(fix$F$a$I$b2$)",
+  "fixtab[$A][$B][1] = CODE_FOR_$(fixuns$F$a$b2$)",
+  "fixtrunctab[$A][$B][0] = CODE_FOR_$(fix_trunc$F$a$I$b2$)",
+  "fixtrunctab[$A][$B][1] = CODE_FOR_$(fixuns_trunc$F$a$I$b2$)",
+  "floattab[$B][$A][0] = CODE_FOR_$(float$I$a$F$b2$)",
+  "floattab[$B][$A][1] = CODE_FOR_$(floatuns$I$a$F$b2$)",
+  "add_optab->handlers[$A].insn_code = CODE_FOR_$(add$P$a3$)",
+  "addv_optab->handlers[(int) $A].insn_code =\n\
+    add_optab->handlers[(int) $A].insn_code = CODE_FOR_$(add$F$a3$)",
+  "addv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(addv$I$a3$)",
+  "sub_optab->handlers[$A].insn_code = CODE_FOR_$(sub$P$a3$)",
+  "subv_optab->handlers[(int) $A].insn_code =\n\
+    sub_optab->handlers[(int) $A].insn_code = CODE_FOR_$(sub$F$a3$)",
+  "subv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(subv$I$a3$)",
+  "smul_optab->handlers[$A].insn_code = CODE_FOR_$(mul$P$a3$)",
+  "smulv_optab->handlers[(int) $A].insn_code =\n\
+    smul_optab->handlers[(int) $A].insn_code = CODE_FOR_$(mul$F$a3$)",
+  "smulv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(mulv$I$a3$)",
+  "umul_highpart_optab->handlers[$A].insn_code = CODE_FOR_$(umul$a3_highpart$)",
+  "smul_highpart_optab->handlers[$A].insn_code = CODE_FOR_$(smul$a3_highpart$)",
+  "smul_widen_optab->handlers[$B].insn_code = CODE_FOR_$(mul$a$b3$)$N",
+  "umul_widen_optab->handlers[$B].insn_code = CODE_FOR_$(umul$a$b3$)$N",
+  "sdiv_optab->handlers[$A].insn_code = CODE_FOR_$(div$a3$)",
+  "sdivv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(div$V$I$a3$)",
+  "udiv_optab->handlers[$A].insn_code = CODE_FOR_$(udiv$I$a3$)",
+  "sdivmod_optab->handlers[$A].insn_code = CODE_FOR_$(divmod$a4$)",
+  "udivmod_optab->handlers[$A].insn_code = CODE_FOR_$(udivmod$a4$)",
+  "smod_optab->handlers[$A].insn_code = CODE_FOR_$(mod$a3$)",
+  "umod_optab->handlers[$A].insn_code = CODE_FOR_$(umod$a3$)",
+  "ftrunc_optab->handlers[$A].insn_code = CODE_FOR_$(ftrunc$F$a2$)",
+  "and_optab->handlers[$A].insn_code = CODE_FOR_$(and$a3$)",
+  "ior_optab->handlers[$A].insn_code = CODE_FOR_$(ior$a3$)",
+  "xor_optab->handlers[$A].insn_code = CODE_FOR_$(xor$a3$)",
+  "ashl_optab->handlers[$A].insn_code = CODE_FOR_$(ashl$a3$)",
+  "ashr_optab->handlers[$A].insn_code = CODE_FOR_$(ashr$a3$)",
+  "lshr_optab->handlers[$A].insn_code = CODE_FOR_$(lshr$a3$)",
+  "rotl_optab->handlers[$A].insn_code = CODE_FOR_$(rotl$a3$)",
+  "rotr_optab->handlers[$A].insn_code = CODE_FOR_$(rotr$a3$)",
+  "smin_optab->handlers[$A].insn_code = CODE_FOR_$(smin$I$a3$)",
+  "smin_optab->handlers[$A].insn_code = CODE_FOR_$(min$F$a3$)",
+  "smax_optab->handlers[$A].insn_code = CODE_FOR_$(smax$I$a3$)",
+  "smax_optab->handlers[$A].insn_code = CODE_FOR_$(max$F$a3$)",
+  "umin_optab->handlers[$A].insn_code = CODE_FOR_$(umin$I$a3$)",
+  "umax_optab->handlers[$A].insn_code = CODE_FOR_$(umax$I$a3$)",
+  "neg_optab->handlers[$A].insn_code = CODE_FOR_$(neg$P$a2$)",
+  "negv_optab->handlers[(int) $A].insn_code =\n\
+    neg_optab->handlers[(int) $A].insn_code = CODE_FOR_$(neg$F$a2$)",
+  "negv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(negv$I$a2$)",
+  "abs_optab->handlers[$A].insn_code = CODE_FOR_$(abs$P$a2$)",
+  "absv_optab->handlers[(int) $A].insn_code =\n\
+    abs_optab->handlers[(int) $A].insn_code = CODE_FOR_$(abs$F$a2$)",
+  "absv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(absv$I$a2$)",
+  "sqrt_optab->handlers[$A].insn_code = CODE_FOR_$(sqrt$a2$)",
+  "sin_optab->handlers[$A].insn_code = CODE_FOR_$(sin$a2$)",
+  "cos_optab->handlers[$A].insn_code = CODE_FOR_$(cos$a2$)",
+  "strlen_optab->handlers[$A].insn_code = CODE_FOR_$(strlen$a$)",
+  "one_cmpl_optab->handlers[$A].insn_code = CODE_FOR_$(one_cmpl$a2$)",
+  "ffs_optab->handlers[$A].insn_code = CODE_FOR_$(ffs$a2$)",
+  "mov_optab->handlers[$A].insn_code = CODE_FOR_$(mov$a$)",
+  "movstrict_optab->handlers[$A].insn_code = CODE_FOR_$(movstrict$a$)",
+  "cmp_optab->handlers[$A].insn_code = CODE_FOR_$(cmp$a$)",
+  "tst_optab->handlers[$A].insn_code = CODE_FOR_$(tst$a$)",
+  "bcc_gen_fctn[$C] = gen_$(b$c$)",
+  "setcc_gen_code[$C] = CODE_FOR_$(s$c$)",
+  "movcc_gen_code[$A] = CODE_FOR_$(mov$acc$)",
+  "cbranch_optab->handlers[$A].insn_code = CODE_FOR_$(cbranch$a4$)",
+  "cmov_optab->handlers[$A].insn_code = CODE_FOR_$(cmov$a6$)",
+  "cstore_optab->handlers[$A].insn_code = CODE_FOR_$(cstore$a4$)",
+  "push_optab->handlers[$A].insn_code = CODE_FOR_$(push$a1$)",
+  "reload_in_optab[$A] = CODE_FOR_$(reload_in$a$)",
+  "reload_out_optab[$A] = CODE_FOR_$(reload_out$a$)",
+  "movstr_optab[$A] = CODE_FOR_$(movstr$a$)",
+  "clrstr_optab[$A] = CODE_FOR_$(clrstr$a$)" };
+
+static void gen_insn PARAMS ((rtx));
 
 static void
 gen_insn (insn)
      rtx insn;
 {
-  char *name = XSTR (insn, 0);
-  int m1, m2, op;
+  const char *name = XSTR (insn, 0);
+  int m1 = 0, m2 = 0, op = 0;
   size_t pindex;
   int i;
-  char *np, *pp, *p, *q;
+  const char *np, *pp, *p, *q;
 
   /* Don't mention instructions whose names are the null string.
      They are in the machine description just to be recognized.  */
@@ -145,19 +153,19 @@ gen_insn (insn)
   /* See if NAME matches one of the patterns we have for the optabs we know
      about.  */
 
-  for (pindex = 0; pindex < sizeof optabs / sizeof optabs[0]; pindex++)
+  for (pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
     {
-      int force_float = 0, force_int = 0;
+      int force_float = 0, force_int = 0, force_partial_int = 0;
       int force_consec = 0;
       int matches = 1;
 
-      for (pp = optabs[pindex]; pp[0] != '%' || pp[1] != '('; pp++)
+      for (pp = optabs[pindex]; pp[0] != '$' || pp[1] != '('; pp++)
        ;
 
-      for (pp += 2, np = name; matches && ! (pp[0] == '%' && pp[1] == ')');
+      for (pp += 2, np = name; matches && ! (pp[0] == '$' && pp[1] == ')');
           pp++)
        {
-         if (*pp != '%')
+         if (*pp != '$')
            {
              if (*pp != *np++)
                break;
@@ -171,27 +179,32 @@ gen_insn (insn)
              case 'I':
                force_int = 1;
                break;
+             case 'P':
+                force_partial_int = 1;
+                break;
              case 'F':
                force_float = 1;
                break;
+             case 'V':
+                break;
              case 'c':
                for (op = 0; op < NUM_RTX_CODE; op++)
                  {
-                   for (p = rtx_name[op], q = np; *p; p++, q++)
+                   for (p = GET_RTX_NAME(op), q = np; *p; p++, q++)
                      if (*p != *q)
                        break;
 
                    /* We have to be concerned about matching "gt" and
                       missing "gtu", e.g., so verify we have reached the
                       end of thing we are to match.  */
-                   if (*p == 0 && *q == 0 && rtx_class[op] == '<')
+                   if (*p == 0 && *q == 0 && GET_RTX_CLASS(op) == '<')
                      break;
                  }
 
                if (op == NUM_RTX_CODE)
                  matches = 0;
                else
-                 np += strlen (rtx_name[op]);
+                 np += strlen (GET_RTX_NAME(op));
                break;
              case 'a':
              case 'b':
@@ -201,24 +214,30 @@ gen_insn (insn)
                    CC modes (as it should be).  */
                for (i = ((int) MAX_MACHINE_MODE) - 1; i >= 0; i--)
                  {
-                   for (p = mode_name[i], q = np; *p; p++, q++)
-                     if (tolower ((unsigned char)*p) != *q)
+                   for (p = GET_MODE_NAME(i), q = np; *p; p++, q++)
+                     if (TOLOWER (*p) != *q)
                        break;
 
                    if (*p == 0
-                       && (! force_int || mode_class[i] == MODE_INT)
-                       && (! force_float || mode_class[i] == MODE_FLOAT))
+                       && (! force_int || mode_class[i] == MODE_INT 
+                           || mode_class[i] == MODE_VECTOR_INT)
+                       && (! force_partial_int
+                            || mode_class[i] == MODE_INT
+                            || mode_class[i] == MODE_PARTIAL_INT
+                           || mode_class[i] == MODE_VECTOR_INT)
+                       && (! force_float || mode_class[i] == MODE_FLOAT 
+                           || mode_class[i] == MODE_VECTOR_FLOAT))
                      break;
                  }
 
                if (i < 0)
                  matches = 0;
                else if (*pp == 'a')
-                 m1 = i, np += strlen (mode_name[i]);
+                 m1 = i, np += strlen (GET_MODE_NAME(i));
                else
-                 m2 = i, np += strlen (mode_name[i]);
+                 m2 = i, np += strlen (GET_MODE_NAME(i));
 
-               force_int = force_float = 0;
+               force_int = force_partial_int = force_float = 0;
                break;
 
              default:
@@ -226,13 +245,13 @@ gen_insn (insn)
              }
        }
 
-      if (matches && pp[0] == '%' && pp[1] == ')'
+      if (matches && pp[0] == '$' && pp[1] == ')'
          && *np == 0
          && (! force_consec || (int) GET_MODE_WIDER_MODE(m1) == m2))
        break;
     }
 
-  if (pindex == sizeof optabs / sizeof optabs[0])
+  if (pindex == ARRAY_SIZE (optabs))
     return;
 
   /* We found a match.  If this pattern is only conditionally present,
@@ -246,116 +265,62 @@ gen_insn (insn)
   /* Now write out the initialization, making all required substitutions.  */
   for (pp = optabs[pindex]; *pp; pp++)
     {
-      if (*pp != '%')
-       printf ("%c", *pp);
+      if (*pp != '$')
+       putchar (*pp);
       else
        switch (*++pp)
          {
          case '(':  case ')':
          case 'I':  case 'F':  case 'N':
            break;
+         case 'V':
+            if (GET_MODE_CLASS (m1) == MODE_FLOAT)
+              printf ("v");
+            break;
          case 'a':
-           for (np = mode_name[m1]; *np; np++)
-             printf ("%c", tolower ((unsigned char)*np));
+           for (np = GET_MODE_NAME(m1); *np; np++)
+             putchar (TOLOWER (*np));
            break;
          case 'b':
-           for (np = mode_name[m2]; *np; np++)
-             printf ("%c", tolower ((unsigned char)*np));
+           for (np = GET_MODE_NAME(m2); *np; np++)
+             putchar (TOLOWER (*np));
            break;
          case 'A':
-           printf ("%smode", mode_name[m1]);
+           printf ("(int) %smode", GET_MODE_NAME(m1));
            break;
          case 'B':
-           printf ("%smode", mode_name[m2]);
+           printf ("(int) %smode", GET_MODE_NAME(m2));
            break;
          case 'c':
-           printf ("%s", rtx_name[op]);
+           printf ("%s", GET_RTX_NAME(op));
            break;
          case 'C':
-           for (np = rtx_name[op]; *np; np++)
-             printf ("%c", toupper ((unsigned char)*np));
+           printf ("(int) ");
+           for (np = GET_RTX_NAME(op); *np; np++)
+             putchar (TOUPPER (*np));
            break;
          }
     }
 
   printf (";\n");
 }
-\f
-char *
-xmalloc (size)
-     unsigned size;
-{
-  register char *val = (char *) malloc (size);
-
-  if (val == 0)
-    fatal ("virtual memory exhausted");
-
-  return val;
-}
 
-char *
-xrealloc (ptr, size)
-     char *ptr;
-     unsigned size;
-{
-  char *result = (char *) realloc (ptr, size);
-  if (!result)
-    fatal ("virtual memory exhausted");
-  return result;
-}
+extern int main PARAMS ((int, char **));
 
-static void
-fatal VPROTO ((char *format, ...))
-{
-#ifndef ANSI_PROTOTYPES
-  char *format;
-#endif
-  va_list ap;
-
-  VA_START (ap, format);
-
-#ifndef ANSI_PROTOTYPES
-  format = va_arg (ap, char *);
-#endif
-
-  fprintf (stderr, "genopinit: ");
-  vfprintf (stderr, format, ap);
-  va_end (ap);
-  fprintf (stderr, "\n");
-  exit (FATAL_EXIT_CODE);
-}
-
-/* More 'friendly' abort that prints the line and file.
-   config.h can #define abort fancy_abort if you like that sort of thing.  */
-
-void
-fancy_abort ()
-{
-  fatal ("Internal gcc abort.");
-}
-\f
 int
 main (argc, argv)
      int argc;
      char **argv;
 {
   rtx desc;
-  FILE *infile;
-  register int c;
 
-  obstack_init (rtl_obstack);
+  progname = "genopinit";
 
   if (argc <= 1)
-    fatal ("No input file name.");
+    fatal ("no input file name");
 
-  infile = fopen (argv[1], "r");
-  if (infile == 0)
-    {
-      perror (argv[1]);
-      exit (FATAL_EXIT_CODE);
-    }
-
-  init_rtl ();
+  if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
+    return (FATAL_EXIT_CODE);
 
   printf ("/* Generated automatically by the program `genopinit'\n\
 from the machine description file `md'.  */\n\n");
@@ -364,11 +329,10 @@ from the machine description file `md'.  */\n\n");
   printf ("#include \"system.h\"\n");
   printf ("#include \"rtl.h\"\n");
   printf ("#include \"flags.h\"\n");
-  printf ("#include \"insn-flags.h\"\n");
-  printf ("#include \"insn-codes.h\"\n");
   printf ("#include \"insn-config.h\"\n");
   printf ("#include \"recog.h\"\n");
   printf ("#include \"expr.h\"\n");
+  printf ("#include \"optabs.h\"\n");
   printf ("#include \"reload.h\"\n\n");
 
   printf ("void\ninit_all_optabs ()\n{\n");
@@ -377,12 +341,12 @@ from the machine description file `md'.  */\n\n");
 
   while (1)
     {
-      c = read_skip_spaces (infile);
-      if (c == EOF)
+      int line_no, insn_code_number = 0;
+
+      desc = read_md_rtx (&line_no, &insn_code_number);
+      if (desc == NULL)
        break;
-      ungetc (c, infile);
 
-      desc = read_rtx (infile);
       if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
        gen_insn (desc);
     }
@@ -390,7 +354,13 @@ from the machine description file `md'.  */\n\n");
   printf ("}\n");
 
   fflush (stdout);
-  exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
-  /* NOTREACHED */
-  return 0;
+  return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
+}
+
+/* Define this so we can link with print-rtl.o to get debug_rtx function.  */
+const char *
+get_insn_name (code)
+     int code ATTRIBUTE_UNUSED;
+{
+  return NULL;
 }