/* Generate from machine description:

   - some flags HAVE_... saying which simple standard instructions are
   available for this machine.
   Copyright (C) 1987, 1991, 1995, 1998 Free Software Foundation, Inc.

This file is part of GNU CC.

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.

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.

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.  */


#include "hconfig.h"
#ifdef __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include "system.h"
#include "rtl.h"
#include "obstack.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;
void fancy_abort PROTO((void));

/* Names for patterns.  Need to allow linking with print-rtl.  */
char **insn_name_ptr;

/* Obstacks to remember normal, and call insns.  */
static struct obstack call_obstack, normal_obstack;

/* Max size of names encountered.  */
static int max_id_len;

static int num_operands PROTO((rtx));
static void gen_proto PROTO((rtx));
static void gen_nonproto PROTO((rtx));
static void gen_insn PROTO((rtx));


/* Count the number of match_operand's found.  */

static int
num_operands (x)
     rtx x;
{
  int count = 0;
  int i, j;
  enum rtx_code code = GET_CODE (x);
  char *format_ptr = GET_RTX_FORMAT (code);

  if (code == MATCH_OPERAND)
    return 1;

  if (code == MATCH_OPERATOR || code == MATCH_PARALLEL)
    count++;

  for (i = 0; i < GET_RTX_LENGTH (code); i++)
    {
      switch (*format_ptr++)
	{
	case 'u':
	case 'e':
	  count += num_operands (XEXP (x, i));
	  break;

	case 'E':
	  if (XVEC (x, i) != NULL)
	    for (j = 0; j < XVECLEN (x, i); j++)
	      count += num_operands (XVECEXP (x, i, j));

	  break;
	}
    }

  return count;
}

/* Print out prototype information for a function.  */

static void
gen_proto (insn)
     rtx insn;
{
  int num = num_operands (insn);
  printf ("extern rtx gen_%-*s PROTO((", max_id_len, XSTR (insn, 0));

  if (num == 0)
    printf ("void");
  else
    {
      while (num-- > 1)
	printf ("rtx, ");

      printf ("rtx");
    }

  printf ("));\n");
}

/* Print out a function declaration without a prototype.  */

static void
gen_nonproto (insn)
     rtx insn;
{
  printf ("extern rtx gen_%s ();\n", XSTR (insn, 0));
}

static void
gen_insn (insn)
     rtx insn;
{
  char *name = XSTR (insn, 0);
  char *p;
  struct obstack *obstack_ptr;
  int len;

  /* Don't mention instructions whose names are the null string
     or begin with '*'.  They are in the machine description just
     to be recognized.  */
  if (name[0] == 0 || name[0] == '*')
    return;

  len = strlen (name);

  if (len > max_id_len)
    max_id_len = len;

  printf ("#define HAVE_%s ", name);
  if (strlen (XSTR (insn, 2)) == 0)
    printf ("1\n");
  else
    {
      /* Write the macro definition, putting \'s at the end of each line,
	 if more than one.  */
      printf ("(");
      for (p = XSTR (insn, 2); *p; p++)
	{
	  if (*p == '\n')
	    printf (" \\\n");
	  else
	    printf ("%c", *p);
	}
      printf (")\n");
    }

  /* Save the current insn, so that we can later put out appropriate
     prototypes.  At present, most md files have the wrong number of
     arguments for the call insns (call, call_value, call_pop,
     call_value_pop) ignoring the extra arguments that are passed for
     some machines, so by default, turn off the prototype.  */

  obstack_ptr = (name[0] == 'c'
		 && (!strcmp (name, "call")
		     || !strcmp (name, "call_value")
		     || !strcmp (name, "call_pop")
		     || !strcmp (name, "call_value_pop")))
    ? &call_obstack : &normal_obstack;

  obstack_grow (obstack_ptr, &insn, sizeof (rtx));
}

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;
}

static void
fatal VPROTO ((char *format, ...))
{
#ifndef __STDC__
  char *format;
#endif
  va_list ap;

  VA_START (ap, format);

#ifndef __STDC__
  format = va_arg (ap, char *);
#endif

  fprintf (stderr, "genflags: ");
  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.");
}

int
main (argc, argv)
     int argc;
     char **argv;
{
  rtx desc;
  rtx dummy;
  rtx *call_insns;
  rtx *normal_insns;
  rtx *insn_ptr;
  FILE *infile;
  register int c;

  obstack_init (rtl_obstack);
  obstack_init (&call_obstack);
  obstack_init (&normal_obstack);

  if (argc <= 1)
    fatal ("No input file name.");

  infile = fopen (argv[1], "r");
  if (infile == 0)
    {
      perror (argv[1]);
      exit (FATAL_EXIT_CODE);
    }

  init_rtl ();

  printf ("/* Generated automatically by the program `genflags'\n\
from the machine description file `md'.  */\n\n");

  /* Read the machine description.  */

  while (1)
    {
      c = read_skip_spaces (infile);
      if (c == EOF)
	break;
      ungetc (c, infile);

      desc = read_rtx (infile);
      if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
	gen_insn (desc);
    }

  /* Print out the prototypes now.  */
  dummy = (rtx) 0;
  obstack_grow (&call_obstack, &dummy, sizeof (rtx));
  call_insns = (rtx *) obstack_finish (&call_obstack);

  obstack_grow (&normal_obstack, &dummy, sizeof (rtx));
  normal_insns = (rtx *) obstack_finish (&normal_obstack);

  printf ("\n#ifndef NO_MD_PROTOTYPES\n");
  for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
    gen_proto (*insn_ptr);

  printf ("\n#ifdef MD_CALL_PROTOTYPES\n");
  for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
    gen_proto (*insn_ptr);

  printf ("\n#else /* !MD_CALL_PROTOTYPES */\n");
  for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
    gen_nonproto (*insn_ptr);

  printf ("#endif /* !MD_CALL_PROTOTYPES */\n");
  printf ("\n#else  /* NO_MD_PROTOTYPES */\n");
  for (insn_ptr = normal_insns; *insn_ptr; insn_ptr++)
    gen_nonproto (*insn_ptr);

  for (insn_ptr = call_insns; *insn_ptr; insn_ptr++)
    gen_nonproto (*insn_ptr);

  printf ("#endif  /* NO_MD_PROTOTYPES */\n");

  fflush (stdout);
  exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
  /* NOTREACHED */
  return 0;
}
