/* Generate code from machine description to extract operands from insn as rtl.
   Copyright (C) 1987, 1991, 1992, 1993, 1997, 1998, 1999, 2000, 2003,
   2004, 2005, 2007, 2008
   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 3, 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 COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */


#include "bconfig.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "errors.h"
#include "gensupport.h"
#include "vec.h"
#include "vecprim.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.  */

typedef char *locstr;

struct extraction
{
  unsigned int op_count;
  unsigned int dup_count;
  locstr *oplocs;
  locstr *duplocs;
  int *dupnums;
  struct code_ptr *insns;
  struct extraction *next;
};

/* Holds a single insn code that uses an extraction method.  */
struct code_ptr
{
  int insn_code;
  struct code_ptr *next;
};

/* All extractions needed for this machine description.  */
static struct extraction *extractions;

/* All insn codes for old-style peepholes.  */
static struct code_ptr *peepholes;

/* This structure is used by gen_insn and walk_rtx to accumulate the
   data that will be used to produce an extractions structure.  */

DEF_VEC_P(locstr);
DEF_VEC_ALLOC_P(locstr,heap);

struct accum_extract
{
  VEC(locstr,heap) *oplocs;
  VEC(locstr,heap) *duplocs;
  VEC(int,heap)    *dupnums;
  VEC(char,heap)   *pathstr;
};

/* Forward declarations.  */
static void walk_rtx (rtx, struct accum_extract *);

static void
gen_insn (rtx insn, int insn_code_number)
{
  int i;
  unsigned int op_count, dup_count, j;
  struct extraction *p;
  struct code_ptr *link;
  struct accum_extract acc;

  acc.oplocs  = VEC_alloc (locstr,heap, 10);
  acc.duplocs = VEC_alloc (locstr,heap, 10);
  acc.dupnums = VEC_alloc (int,heap,    10);
  acc.pathstr = VEC_alloc (char,heap,   20);

  /* 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), &acc);
  else
    for (i = XVECLEN (insn, 1) - 1; i >= 0; i--)
      {
	VEC_safe_push (char,heap, acc.pathstr, 'a' + i);
	walk_rtx (XVECEXP (insn, 1, i), &acc);
	VEC_pop (char, acc.pathstr);
      }

  link = XNEW (struct code_ptr);
  link->insn_code = insn_code_number;

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

  op_count = VEC_length (locstr, acc.oplocs);
  dup_count = VEC_length (locstr, acc.duplocs);
  gcc_assert (dup_count == VEC_length (int, acc.dupnums));

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

      for (j = 0; j < op_count; j++)
	{
	  char *a = p->oplocs[j];
	  char *b = VEC_index (locstr, acc.oplocs, j);
	  if (a != b && (!a || !b || strcmp (a, b)))
	    break;
	}

      if (j != op_count)
	continue;

      for (j = 0; j < dup_count; j++)
	if (p->dupnums[j] != VEC_index (int, acc.dupnums, j)
	    || strcmp (p->duplocs[j], VEC_index (locstr, acc.duplocs, j)))
	  break;

      if (j != dup_count)
	continue;

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

  /* Otherwise, make a new extraction method.  We stash the arrays
     after the extraction structure in memory.  */

  p = XNEWVAR (struct extraction, sizeof (struct extraction)
	       + op_count*sizeof (char *)
	       + dup_count*sizeof (char *)
	       + dup_count*sizeof (int));
  p->op_count = op_count;
  p->dup_count = dup_count;
  p->next = extractions;
  extractions = p;
  p->insns = link;
  link->next = 0;

  p->oplocs = (char **)((char *)p + sizeof (struct extraction));
  p->duplocs = p->oplocs + op_count;
  p->dupnums = (int *)(p->duplocs + dup_count);

  memcpy(p->oplocs,  VEC_address(locstr,acc.oplocs),   op_count*sizeof(locstr));
  memcpy(p->duplocs, VEC_address(locstr,acc.duplocs), dup_count*sizeof(locstr));
  memcpy(p->dupnums, VEC_address(int,   acc.dupnums), dup_count*sizeof(int));

 done:
  VEC_free (locstr,heap, acc.oplocs);
  VEC_free (locstr,heap, acc.duplocs);
  VEC_free (int,heap,    acc.dupnums);
  VEC_free (char,heap,   acc.pathstr);
}

/* Helper subroutine of walk_rtx: given a VEC(locstr), an index, and a
   string, insert the string at the index, which should either already
   exist and be NULL, or not yet exist within the vector.  In the latter
   case the vector is enlarged as appropriate.  */
static void
VEC_safe_set_locstr (VEC(locstr,heap) **vp, unsigned int ix, char *str)
{
  if (ix < VEC_length (locstr, *vp))
    {
      gcc_assert (VEC_index (locstr, *vp, ix) == 0);
      VEC_replace (locstr, *vp, ix, str);
    }
  else
    {
      while (ix > VEC_length (locstr, *vp))
	VEC_safe_push (locstr, heap, *vp, 0);
      VEC_safe_push (locstr, heap, *vp, str);
    }
}

/* Another helper subroutine of walk_rtx: given a VEC(char), convert it
   to a NUL-terminated string in malloc memory.  */
static char *
VEC_char_to_string (VEC(char,heap) *v)
{
  size_t n = VEC_length (char, v);
  char *s = XNEWVEC (char, n + 1);
  memcpy (s, VEC_address (char, v), n);
  s[n] = '\0';
  return s;
}

static void
walk_rtx (rtx x, struct accum_extract *acc)
{
  RTX_CODE code;
  int i, len, base;
  const char *fmt;

  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:
      VEC_safe_set_locstr (&acc->oplocs, XINT (x, 0),
			   VEC_char_to_string (acc->pathstr));
      break;

    case MATCH_OPERATOR:
    case MATCH_PARALLEL:
      VEC_safe_set_locstr (&acc->oplocs, XINT (x, 0),
			   VEC_char_to_string (acc->pathstr));

      base = (code == MATCH_OPERATOR ? '0' : 'a');
      for (i = XVECLEN (x, 2) - 1; i >= 0; i--)
	{
	  VEC_safe_push (char,heap, acc->pathstr, base + i);
	  walk_rtx (XVECEXP (x, 2, i), acc);
	  VEC_pop (char, acc->pathstr);
        }
      return;

    case MATCH_DUP:
    case MATCH_PAR_DUP:
    case MATCH_OP_DUP:
      VEC_safe_push (locstr,heap, acc->duplocs,
		     VEC_char_to_string (acc->pathstr));
      VEC_safe_push (int,heap, acc->dupnums, XINT (x, 0));

      if (code == MATCH_DUP)
	break;

      base = (code == MATCH_OP_DUP ? '0' : 'a');
      for (i = XVECLEN (x, 1) - 1; i >= 0; i--)
        {
	  VEC_safe_push (char,heap, acc->pathstr, base + i);
	  walk_rtx (XVECEXP (x, 1, i), acc);
	  VEC_pop (char, acc->pathstr);
        }
      return;

    default:
      break;
    }

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

/* 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.  */
      fputs ("PATTERN (insn)", stdout);
      return;
    }

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

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

  fputs ("pat", stdout);

  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 ();
    }
}

static void
print_header (void)
{
  /* N.B. Code below avoids putting squiggle braces in column 1 inside
     a string, because this confuses some editors' syntax highlighting
     engines.  */

  puts ("\
/* Generated automatically by the program `genextract'\n\
   from the machine description file `md'.  */\n\
\n\
#include \"config.h\"\n\
#include \"system.h\"\n\
#include \"coretypes.h\"\n\
#include \"tm.h\"\n\
#include \"rtl.h\"\n\
#include \"insn-config.h\"\n\
#include \"recog.h\"\n\
#include \"toplev.h\"\n\
\n\
/* This variable is used as the \"location\" of any missing operand\n\
   whose numbers are skipped by a given pattern.  */\n\
static rtx junk ATTRIBUTE_UNUSED;\n");

  puts ("\
void\n\
insn_extract (rtx insn)\n{\n\
  rtx *ro = recog_data.operand;\n\
  rtx **ro_loc = recog_data.operand_loc;\n\
  rtx pat = PATTERN (insn);\n\
  int i ATTRIBUTE_UNUSED; /* only for peepholes */\n\
\n\
#ifdef ENABLE_CHECKING\n\
  memset (ro, 0xab, sizeof (*ro) * MAX_RECOG_OPERANDS);\n\
  memset (ro_loc, 0xab, sizeof (*ro_loc) * MAX_RECOG_OPERANDS);\n\
#endif\n");

  puts ("\
  switch (INSN_CODE (insn))\n\
    {\n\
    default:\n\
      /* Control reaches here if insn_extract has been called with an\n\
         unrecognizable insn (code -1), or an insn whose INSN_CODE\n\
         corresponds to a DEFINE_EXPAND in the machine description;\n\
         either way, a bug.  */\n\
      if (INSN_CODE (insn) < 0)\n\
        fatal_insn (\"unrecognizable insn:\", insn);\n\
      else\n\
        fatal_insn (\"insn with invalid code number:\", insn);\n");
}

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

  progname = "genextract";

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

  /* Read the machine description.  */

  while ((desc = read_md_rtx (&line_no, &insn_code_number)) != NULL)
    {
       if (GET_CODE (desc) == DEFINE_INSN)
	 gen_insn (desc, insn_code_number);

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

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

  print_header ();

  /* 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.  */
      puts ("      for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)\n"
	    "          ro[i] = *(ro_loc[i] = &XVECEXP (pat, 0, i));\n"
	    "      break;\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]);
	      puts (");");
	    }
	}

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

      puts ("      break;\n");
    }

  puts ("    }\n}");
  fflush (stdout);
  return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
}
