/* Process machine description and calculate constant conditions.
   Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.

   This file is part of GCC.

   GCC is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   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 GCC; see the file COPYING.  If not, write to
   the Free Software Foundation, 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

/* In a machine description, all of the insn patterns - define_insn,
   define_expand, define_split, define_peephole, define_peephole2 -
   contain an optional C expression which makes the final decision
   about whether or not this pattern is usable.  That expression may
   turn out to be always false when the compiler is built.  If it is,
   most of the programs that generate code from the machine
   description can simply ignore the entire pattern.  */

#include "bconfig.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "errors.h"
#include "hashtab.h"
#include "gensupport.h"

/* so we can include except.h in the generated file.  */
static int saw_eh_return;

static htab_t condition_table;

static void add_condition	(const char *);
static void write_header	(void);
static void write_conditions	(void);
static int write_one_condition	(void **, void *);

/* Record the C test expression EXPR in the condition_table.
   Duplicates clobber previous entries, which leaks memory, but
   we don't care for this application.  */

static void
add_condition (const char *expr)
{
  struct c_test *test;

  if (expr[0] == 0)
    return;

  test = XNEW (struct c_test);
  test->expr = expr;

  *(htab_find_slot (condition_table, test, INSERT)) = test;
}

/* Generate the header for insn-conditions.c.  */

static void
write_header (void)
{
  puts ("\
/* Generated automatically by the program `genconditions' from the target\n\
   machine description file.  */\n\
\n\
#include \"bconfig.h\"\n\
#include \"insn-constants.h\"\n");

  puts ("\
/* Do not allow checking to confuse the issue.  */\n\
#undef ENABLE_CHECKING\n\
#undef ENABLE_TREE_CHECKING\n\
#undef ENABLE_RTL_CHECKING\n\
#undef ENABLE_RTL_FLAG_CHECKING\n\
#undef ENABLE_GC_CHECKING\n\
#undef ENABLE_GC_ALWAYS_COLLECT\n");

  puts ("\
#include \"system.h\"\n\
#if GCC_VERSION < 3001\n\
#include \"dummy-conditions.c\"\n\
#else\n\
#include \"coretypes.h\"\n\
#include \"tm.h\"\n\
#include \"rtl.h\"\n\
#include \"tm_p.h\"\n\
#include \"function.h\"\n");

  puts ("\
/* Fake - insn-config.h doesn't exist yet.  */\n\
#define MAX_RECOG_OPERANDS 10\n\
#define MAX_DUP_OPERANDS 10\n\
#define MAX_INSNS_PER_SPLIT 5\n");

  puts ("\
#include \"regs.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 \"toplev.h\"\n\
#include \"reload.h\"\n\
#include \"gensupport.h\"\n");

  if (saw_eh_return)
    puts ("#define HAVE_eh_return 1");
  puts ("#include \"except.h\"\n");

  puts ("\
/* Dummy external declarations.  */\n\
extern rtx insn;\n\
extern rtx ins1;\n\
extern rtx operands[];\n");

  puts ("\
/* If we don't have __builtin_constant_p, or it's not acceptable in\n\
   array initializers, fall back (by using dummy-conditions.c above)\n\
   to assuming that all conditions potentially vary at run time.  It\n\
   works in 3.0.1 and later; 3.0 only when not optimizing.  */\n\
#define MAYBE_EVAL(expr) (__builtin_constant_p(expr) ? (int) (expr) : -1)\n");
}

/* Write out one entry in the conditions table, using the data pointed
   to by SLOT.  Each entry looks like this:
  { "! optimize_size && ! TARGET_READ_MODIFY_WRITE",
    MAYBE_EVAL (! optimize_size && ! TARGET_READ_MODIFY_WRITE) },  */

static int
write_one_condition (void **slot, void * ARG_UNUSED (dummy))
{
  const struct c_test *test = * (const struct c_test **) slot;
  const char *p;

  fputs ("  { \"", stdout);
  for (p = test->expr; *p; p++)
    {
      if (*p == '\n')
	fputs ("\\n\\\n", stdout);
      else if (*p == '"')
	fputs ("\\\"", stdout);
      else
	putchar (*p);
    }

  printf ("\",\n    MAYBE_EVAL (%s) },\n", test->expr);
  return 1;
}

/* Write out the complete conditions table, its size, and a flag
   indicating that gensupport.c can now do insn elision.  */
static void
write_conditions (void)
{
  puts ("\
/* This table lists each condition found in the machine description.\n\
   Each condition is mapped to its truth value (0 or 1), or -1 if that\n\
   cannot be calculated at compile time. */\n\
\n\
const struct c_test insn_conditions[] = {");

  htab_traverse (condition_table, write_one_condition, 0);

  puts ("};\n");

  printf ("const size_t n_insn_conditions = %lu;\n",
	  (unsigned long) htab_elements (condition_table));
  puts ("const int insn_elision_unavailable = 0;\n#endif");
}

int
main (int argc, char **argv)
{
  rtx desc;
  int pattern_lineno; /* not used */
  int code;

  progname = "genconditions";

  if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
    return (FATAL_EXIT_CODE);

  condition_table = htab_create (1000, hash_c_test, cmp_c_test, NULL);

  /* Read the machine description.  */

  while (1)
    {
      desc = read_md_rtx (&pattern_lineno, &code);
      if (desc == NULL)
	break;

      /* N.B. define_insn_and_split, define_cond_exec are handled
	 entirely within read_md_rtx; we never see them.  */
      switch (GET_CODE (desc))
	{
	default:
	  break;

	case DEFINE_INSN:
	case DEFINE_EXPAND:
	  add_condition (XSTR (desc, 2));
	  /* except.h needs to know whether there is an eh_return
	     pattern in the machine description.  */
	  if (!strcmp (XSTR (desc, 0), "eh_return"))
	    saw_eh_return = 1;
	  break;

	case DEFINE_SPLIT:
	case DEFINE_PEEPHOLE:
	case DEFINE_PEEPHOLE2:
	  add_condition (XSTR (desc, 1));
	  break;
	}
    }

  write_header ();
  write_conditions ();

  fflush (stdout);
  return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
}
