/* Generate code from machine description to extract operands from insn as rtl.
   Copyright (C) 1987, 1991, 1992, 1993, 1997, 1998, 1999, 2000, 2003, 2004
   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.  */


#include "bconfig.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "errors.h"
#include "insn-config.h"
#include "gensupport.h"


/* This structure contains all the information needed to describe one
   set of extractions methods.  Each method may be used by more than
   one pattern if the operands are in the same place.

   The string for each operand describes that path to the operand and
   contains `0' through `9' when going into an expression and `a' through
   `z' when going into a vector.  We assume here that only the first operand
   of an rtl expression is a vector.  genrecog.c makes the same assumption
   (and uses the same representation) and it is currently true.  */

struct extraction
{
  int op_count;
  char *oplocs[MAX_RECOG_OPERANDS];
  int dup_count;
  char *duplocs[MAX_DUP_OPERANDS];
  int dupnums[MAX_DUP_OPERANDS];
  struct code_ptr *insns;
  struct extraction *next;
};

/* Holds a single insn code that use an extraction method.  */

struct code_ptr
{
  int insn_code;
  struct code_ptr *next;
};

static struct extraction *extractions;

/* Holds an array of names indexed by insn_code_number.  */
static char **insn_name_ptr = 0;
static int insn_name_ptr_size = 0;

/* Number instruction patterns handled, starting at 0 for first one.  */

static int insn_code_number;

/* Records the large operand number in this insn.  */

static int op_count;

/* Records the location of any operands using the string format described
   above.  */

static char *oplocs[MAX_RECOG_OPERANDS];

/* Number the occurrences of MATCH_DUP in each instruction,
   starting at 0 for the first occurrence.  */

static int dup_count;

/* Records the location of any MATCH_DUP operands.  */

static char *duplocs[MAX_DUP_OPERANDS];

/* Record the operand number of any MATCH_DUPs.  */

static int dupnums[MAX_DUP_OPERANDS];

/* Record the list of insn_codes for peepholes.  */

static struct code_ptr *peepholes;

static void gen_insn (rtx);
static void walk_rtx (rtx, const char *);
static void print_path (const char *);
static void record_insn_name (int, const char *);

static void
gen_insn (rtx insn)
{
  int i;
  struct extraction *p;
  struct code_ptr *link;

  op_count = 0;
  dup_count = 0;

  /* No operands seen so far in this pattern.  */
  memset (oplocs, 0, sizeof oplocs);

  /* Walk the insn's pattern, remembering at all times the path
     down to the walking point.  */

  if (XVECLEN (insn, 1) == 1)
    walk_rtx (XVECEXP (insn, 1, 0), "");
  else
    for (i = XVECLEN (insn, 1) - 1; i >= 0; i--)
      {
	char path[2];

	path[0] = 'a' + i;
	path[1] = 0;

	walk_rtx (XVECEXP (insn, 1, i), path);
      }

  link = xmalloc (sizeof (struct code_ptr));
  link->insn_code = insn_code_number;

  /* See if we find something that already had this extraction method.  */

  for (p = extractions; p; p = p->next)
    {
      if (p->op_count != op_count || p->dup_count != dup_count)
	continue;

      for (i = 0; i < op_count; i++)
	if (p->oplocs[i] != oplocs[i]
	    && ! (p->oplocs[i] != 0 && oplocs[i] != 0
		  && ! strcmp (p->oplocs[i], oplocs[i])))
	  break;

      if (i != op_count)
	continue;

      for (i = 0; i < dup_count; i++)
	if (p->dupnums[i] != dupnums[i]
	    || strcmp (p->duplocs[i], duplocs[i]))
	  break;

      if (i != dup_count)
	continue;

      /* This extraction is the same as ours.  Just link us in.  */
      link->next = p->insns;
      p->insns = link;
      return;
    }

  /* Otherwise, make a new extraction method.  */

  p = xmalloc (sizeof (struct extraction));
  p->op_count = op_count;
  p->dup_count = dup_count;
  p->next = extractions;
  extractions = p;
  p->insns = link;
  link->next = 0;

  for (i = 0; i < op_count; i++)
    p->oplocs[i] = oplocs[i];

  for (i = 0; i < dup_count; i++)
    p->dupnums[i] = dupnums[i], p->duplocs[i] = duplocs[i];
}

static void
walk_rtx (rtx x, const char *path)
{
  RTX_CODE code;
  int i;
  int len;
  const char *fmt;
  int depth = strlen (path);
  char *newpath;

  if (x == 0)
    return;

  code = GET_CODE (x);

  switch (code)
    {
    case PC:
    case CC0:
    case CONST_INT:
    case SYMBOL_REF:
      return;

    case MATCH_OPERAND:
    case MATCH_SCRATCH:
      oplocs[XINT (x, 0)] = xstrdup (path);
      op_count = MAX (op_count, XINT (x, 0) + 1);
      break;

    case MATCH_DUP:
      duplocs[dup_count] = xstrdup (path);
      dupnums[dup_count] = XINT (x, 0);
      dup_count++;
      break;

    case MATCH_PAR_DUP:
    case MATCH_OP_DUP:
      duplocs[dup_count] = xstrdup (path);
      dupnums[dup_count] = XINT (x, 0);
      dup_count++;

      newpath = xmalloc (depth + 2);
      strcpy (newpath, path);
      newpath[depth + 1] = 0;

      for (i = XVECLEN (x, 1) - 1; i >= 0; i--)
        {
	  newpath[depth] = (code == MATCH_OP_DUP ? '0' : 'a') + i;
	  walk_rtx (XVECEXP (x, 1, i), newpath);
        }
      free (newpath);
      return;

    case MATCH_OPERATOR:
      oplocs[XINT (x, 0)] = xstrdup (path);
      op_count = MAX (op_count, XINT (x, 0) + 1);

      newpath = xmalloc (depth + 2);
      strcpy (newpath, path);
      newpath[depth + 1] = 0;

      for (i = XVECLEN (x, 2) - 1; i >= 0; i--)
	{
	  newpath[depth] = '0' + i;
	  walk_rtx (XVECEXP (x, 2, i), newpath);
	}
      free (newpath);
      return;

    case MATCH_PARALLEL:
      oplocs[XINT (x, 0)] = xstrdup (path);
      op_count = MAX (op_count, XINT (x, 0) + 1);

      newpath = xmalloc (depth + 2);
      strcpy (newpath, path);
      newpath[depth + 1] = 0;

      for (i = XVECLEN (x, 2) - 1; i >= 0; i--)
	{
	  newpath[depth] = 'a' + i;
	  walk_rtx (XVECEXP (x, 2, i), newpath);
	}
      free (newpath);
      return;

    case ADDRESS:
      walk_rtx (XEXP (x, 0), path);
      return;

    default:
      break;
    }

  newpath = xmalloc (depth + 2);
  strcpy (newpath, path);
  newpath[depth + 1] = 0;

  fmt = GET_RTX_FORMAT (code);
  len = GET_RTX_LENGTH (code);
  for (i = 0; i < len; i++)
    {
      if (fmt[i] == 'e' || fmt[i] == 'u')
	{
	  newpath[depth] = '0' + i;
	  walk_rtx (XEXP (x, i), newpath);
	}
      else if (fmt[i] == 'E')
	{
	  int j;
	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
	    {
	      newpath[depth] = 'a' + j;
	      walk_rtx (XVECEXP (x, i, j), newpath);
	    }
	}
    }
  free (newpath);
}

/* Given a PATH, representing a path down the instruction's
   pattern from the root to a certain point, output code to
   evaluate to the rtx at that point.  */

static void
print_path (const char *path)
{
  int len = strlen (path);
  int i;

  if (len == 0)
    {
      /* Don't emit "pat", since we may try to take the address of it,
	 which isn't what is intended.  */
      printf("PATTERN (insn)");
      return;
    }

  /* We first write out the operations (XEXP or XVECEXP) in reverse
     order, then write "insn", then the indices in forward order.  */

  for (i = len - 1; i >= 0 ; i--)
    {
      if (ISLOWER(path[i]))
	printf ("XVECEXP (");
      else if (ISDIGIT(path[i]))
	printf ("XEXP (");
      else
	gcc_unreachable ();
    }

  printf ("pat");

  for (i = 0; i < len; i++)
    {
      if (ISLOWER(path[i]))
	printf (", 0, %d)", path[i] - 'a');
      else if (ISDIGIT(path[i]))
	printf (", %d)", path[i] - '0');
      else
	gcc_unreachable ();
    }
}


int
main (int argc, char **argv)
{
  rtx desc;
  int i;
  struct extraction *p;
  struct code_ptr *link;
  const char *name;

  progname = "genextract";

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

  /* Assign sequential codes to all entries in the machine description
     in parallel with the tables in insn-output.c.  */

  insn_code_number = 0;

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

  printf ("#include \"config.h\"\n");
  printf ("#include \"system.h\"\n");
  printf ("#include \"coretypes.h\"\n");
  printf ("#include \"tm.h\"\n");
  printf ("#include \"rtl.h\"\n");
  printf ("#include \"insn-config.h\"\n");
  printf ("#include \"recog.h\"\n");
  printf ("#include \"toplev.h\"\n\n");

  /* This variable exists only so it can be the "location"
     of any missing operand whose numbers are skipped by a given pattern.  */
  printf ("static rtx junk ATTRIBUTE_UNUSED;\n");

  printf ("void\ninsn_extract (rtx insn)\n");
  printf ("{\n");
  printf ("  rtx *ro = recog_data.operand;\n");
  printf ("  rtx **ro_loc = recog_data.operand_loc;\n");
  printf ("  rtx pat = PATTERN (insn);\n");
  printf ("  int i ATTRIBUTE_UNUSED;\n\n");
#ifdef ENABLE_CHECKING
  printf ("  memset (ro, 0xab, sizeof (*ro) * MAX_RECOG_OPERANDS);\n");
  printf ("  memset (ro_loc, 0xab, sizeof (*ro_loc) * MAX_RECOG_OPERANDS);\n");
#endif
  printf ("  switch (INSN_CODE (insn))\n");
  printf ("    {\n");
  printf ("    case -1:\n");
  printf ("      fatal_insn_not_found (insn);\n\n");

  /* Read the machine description.  */

  while (1)
    {
      int line_no;

      desc = read_md_rtx (&line_no, &insn_code_number);
      if (desc == NULL)
	break;

       if (GET_CODE (desc) == DEFINE_INSN)
	{
	  record_insn_name (insn_code_number, XSTR (desc, 0));
	  gen_insn (desc);
	}

      else if (GET_CODE (desc) == DEFINE_PEEPHOLE)
	{
	  struct code_ptr *link = xmalloc (sizeof (struct code_ptr));

	  link->insn_code = insn_code_number;
	  link->next = peepholes;
	  peepholes = link;
	}
    }

  /* Write out code to handle peepholes and the insn_codes that it should
     be called for.  */
  if (peepholes)
    {
      for (link = peepholes; link; link = link->next)
	printf ("    case %d:\n", link->insn_code);

      /* The vector in the insn says how many operands it has.
	 And all it contains are operands.  In fact, the vector was
	 created just for the sake of this function.  We need to set the
	 location of the operands for sake of simplifications after
	 extraction, like eliminating subregs.  */
      printf ("      for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)\n");
      printf ("          ro[i] = *(ro_loc[i] = &XVECEXP (pat, 0, i));\n");
      printf ("      break;\n\n");
    }

  /* Write out all the ways to extract insn operands.  */
  for (p = extractions; p; p = p->next)
    {
      for (link = p->insns; link; link = link->next)
	{
	  i = link->insn_code;
	  name = get_insn_name (i);
	  if (name)
	    printf ("    case %d:  /* %s */\n", i, name);
	  else
	    printf ("    case %d:\n", i);
	}

      for (i = 0; i < p->op_count; i++)
	{
	  if (p->oplocs[i] == 0)
	    {
	      printf ("      ro[%d] = const0_rtx;\n", i);
	      printf ("      ro_loc[%d] = &junk;\n", i);
	    }
	  else
	    {
	      printf ("      ro[%d] = *(ro_loc[%d] = &", i, i);
	      print_path (p->oplocs[i]);
	      printf (");\n");
	    }
	}

      for (i = 0; i < p->dup_count; i++)
	{
	  printf ("      recog_data.dup_loc[%d] = &", i);
	  print_path (p->duplocs[i]);
	  printf (";\n");
	  printf ("      recog_data.dup_num[%d] = %d;\n", i, p->dupnums[i]);
	}

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

  /* This should never be reached.  Note that we would also reach this abort
   if we tried to extract something whose INSN_CODE was a DEFINE_EXPAND or
   DEFINE_SPLIT, but that is correct.  */
  printf ("    default:\n      gcc_unreachable ();\n");

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

  fflush (stdout);
  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 (int code ATTRIBUTE_UNUSED)
{
  if (code < insn_name_ptr_size)
    return insn_name_ptr[code];
  else
    return NULL;
}

static void
record_insn_name (int code, const char *name)
{
  static const char *last_real_name = "insn";
  static int last_real_code = 0;
  char *new;

  if (insn_name_ptr_size <= code)
    {
      int new_size;
      new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
      insn_name_ptr = xrealloc (insn_name_ptr, sizeof(char *) * new_size);
      memset (insn_name_ptr + insn_name_ptr_size, 0,
	      sizeof(char *) * (new_size - insn_name_ptr_size));
      insn_name_ptr_size = new_size;
    }

  if (!name || name[0] == '\0')
    {
      new = xmalloc (strlen (last_real_name) + 10);
      sprintf (new, "%s+%d", last_real_name, code - last_real_code);
    }
  else
    {
      last_real_name = new = xstrdup (name);
      last_real_code = code;
    }

  insn_name_ptr[code] = new;
}
