/* CGEN generic opcode support.

   Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.

   This file is part of the GNU Binutils and GDB, the GNU debugger.

   This program 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.

   This program 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 this program; if not, write to the Free Software Foundation, Inc.,
   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

#include "sysdep.h"
#include <ctype.h>
#include <stdio.h>
#include "ansidecl.h"
#include "libiberty.h"
#include "bfd.h"
#include "symcat.h"
#include "opcode/cgen.h"

static unsigned int hash_keyword_name
  PARAMS ((const CGEN_KEYWORD *, const char *, int));
static unsigned int hash_keyword_value
  PARAMS ((const CGEN_KEYWORD *, unsigned int));
static void build_keyword_hash_tables
  PARAMS ((CGEN_KEYWORD *));

/* Return number of hash table entries to use for N elements.  */
#define KEYWORD_HASH_SIZE(n) ((n) <= 31 ? 17 : 31)

/* Look up *NAMEP in the keyword table KT.
   The result is the keyword entry or NULL if not found.  */

const CGEN_KEYWORD_ENTRY *
cgen_keyword_lookup_name (kt, name)
     CGEN_KEYWORD *kt;
     const char *name;
{
  const CGEN_KEYWORD_ENTRY *ke;
  const char *p,*n;

  if (kt->name_hash_table == NULL)
    build_keyword_hash_tables (kt);

  ke = kt->name_hash_table[hash_keyword_name (kt, name, 0)];

  /* We do case insensitive comparisons.
     If that ever becomes a problem, add an attribute that denotes
     "do case sensitive comparisons".  */

  while (ke != NULL)
    {
      n = name;
      p = ke->name;

      while (*p
	     && (*p == *n
		 || (isalpha ((unsigned char) *p)
		     && (tolower ((unsigned char) *p)
			 == tolower ((unsigned char) *n)))))
	++n, ++p;

      if (!*p && !*n)
	return ke;

      ke = ke->next_name;
    }

  if (kt->null_entry)
    return kt->null_entry;
  return NULL;
}

/* Look up VALUE in the keyword table KT.
   The result is the keyword entry or NULL if not found.  */

const CGEN_KEYWORD_ENTRY *
cgen_keyword_lookup_value (kt, value)
     CGEN_KEYWORD *kt;
     int value;
{
  const CGEN_KEYWORD_ENTRY *ke;

  if (kt->name_hash_table == NULL)
    build_keyword_hash_tables (kt);

  ke = kt->value_hash_table[hash_keyword_value (kt, value)];

  while (ke != NULL)
    {
      if (value == ke->value)
	return ke;
      ke = ke->next_value;
    }

  return NULL;
}

/* Add an entry to a keyword table.  */

void
cgen_keyword_add (kt, ke)
     CGEN_KEYWORD *kt;
     CGEN_KEYWORD_ENTRY *ke;
{
  unsigned int hash;

  if (kt->name_hash_table == NULL)
    build_keyword_hash_tables (kt);

  hash = hash_keyword_name (kt, ke->name, 0);
  ke->next_name = kt->name_hash_table[hash];
  kt->name_hash_table[hash] = ke;

  hash = hash_keyword_value (kt, ke->value);
  ke->next_value = kt->value_hash_table[hash];
  kt->value_hash_table[hash] = ke;

  if (ke->name[0] == 0)
    kt->null_entry = ke;
}

/* FIXME: Need function to return count of keywords.  */

/* Initialize a keyword table search.
   SPEC is a specification of what to search for.
   A value of NULL means to find every keyword.
   Currently NULL is the only acceptable value [further specification
   deferred].
   The result is an opaque data item used to record the search status.
   It is passed to each call to cgen_keyword_search_next.  */

CGEN_KEYWORD_SEARCH
cgen_keyword_search_init (kt, spec)
     CGEN_KEYWORD *kt;
     const char *spec;
{
  CGEN_KEYWORD_SEARCH search;

  /* FIXME: Need to specify format of PARAMS.  */
  if (spec != NULL)
    abort ();

  if (kt->name_hash_table == NULL)
    build_keyword_hash_tables (kt);

  search.table = kt;
  search.spec = spec;
  search.current_hash = 0;
  search.current_entry = NULL;
  return search;
}

/* Return the next keyword specified by SEARCH.
   The result is the next entry or NULL if there are no more.  */

const CGEN_KEYWORD_ENTRY *
cgen_keyword_search_next (search)
     CGEN_KEYWORD_SEARCH *search;
{
  /* Has search finished?  */
  if (search->current_hash == search->table->hash_table_size)
    return NULL;

  /* Search in progress?  */
  if (search->current_entry != NULL
      /* Anything left on this hash chain?  */
      && search->current_entry->next_name != NULL)
    {
      search->current_entry = search->current_entry->next_name;
      return search->current_entry;
    }

  /* Move to next hash chain [unless we haven't started yet].  */
  if (search->current_entry != NULL)
    ++search->current_hash;

  while (search->current_hash < search->table->hash_table_size)
    {
      search->current_entry = search->table->name_hash_table[search->current_hash];
      if (search->current_entry != NULL)
	return search->current_entry;
      ++search->current_hash;
    }

  return NULL;
}

/* Return first entry in hash chain for NAME.
   If CASE_SENSITIVE_P is non-zero, return a case sensitive hash.  */

static unsigned int
hash_keyword_name (kt, name, case_sensitive_p)
     const CGEN_KEYWORD *kt;
     const char *name;
     int case_sensitive_p;
{
  unsigned int hash;

  if (case_sensitive_p)
    for (hash = 0; *name; ++name)
      hash = (hash * 97) + (unsigned char) *name;
  else
    for (hash = 0; *name; ++name)
      hash = (hash * 97) + (unsigned char) tolower (*name);
  return hash % kt->hash_table_size;
}

/* Return first entry in hash chain for VALUE.  */

static unsigned int
hash_keyword_value (kt, value)
     const CGEN_KEYWORD *kt;
     unsigned int value;
{
  return value % kt->hash_table_size;
}

/* Build a keyword table's hash tables.
   We probably needn't build the value hash table for the assembler when
   we're using the disassembler, but we keep things simple.  */

static void
build_keyword_hash_tables (kt)
     CGEN_KEYWORD *kt;
{
  int i;
  /* Use the number of compiled in entries as an estimate for the
     typical sized table [not too many added at runtime].  */
  unsigned int size = KEYWORD_HASH_SIZE (kt->num_init_entries);

  kt->hash_table_size = size;
  kt->name_hash_table = (CGEN_KEYWORD_ENTRY **)
    xmalloc (size * sizeof (CGEN_KEYWORD_ENTRY *));
  memset (kt->name_hash_table, 0, size * sizeof (CGEN_KEYWORD_ENTRY *));
  kt->value_hash_table = (CGEN_KEYWORD_ENTRY **)
    xmalloc (size * sizeof (CGEN_KEYWORD_ENTRY *));
  memset (kt->value_hash_table, 0, size * sizeof (CGEN_KEYWORD_ENTRY *));

  /* The table is scanned backwards as we want keywords appearing earlier to
     be prefered over later ones.  */
  for (i = kt->num_init_entries - 1; i >= 0; --i)
    cgen_keyword_add (kt, &kt->init_entries[i]);
}

/* Hardware support.  */

/* Lookup a hardware element by its name.
   Returns NULL if NAME is not supported by the currently selected
   mach/isa.  */

const CGEN_HW_ENTRY *
cgen_hw_lookup_by_name (cd, name)
     CGEN_CPU_DESC cd;
     const char *name;
{
  int i;
  const CGEN_HW_ENTRY **hw = cd->hw_table.entries;

  for (i = 0; i < cd->hw_table.num_entries; ++i)
    if (hw[i] && strcmp (name, hw[i]->name) == 0)
      return hw[i];

  return NULL;
}

/* Lookup a hardware element by its number.
   Hardware elements are enumerated, however it may be possible to add some
   at runtime, thus HWNUM is not an enum type but rather an int.
   Returns NULL if HWNUM is not supported by the currently selected mach.  */

const CGEN_HW_ENTRY *
cgen_hw_lookup_by_num (cd, hwnum)
     CGEN_CPU_DESC cd;
     int hwnum;
{
  int i;
  const CGEN_HW_ENTRY **hw = cd->hw_table.entries;

  /* ??? This can be speeded up.  */
  for (i = 0; i < cd->hw_table.num_entries; ++i)
    if (hw[i] && hwnum == hw[i]->type)
      return hw[i];

  return NULL;
}

/* Operand support.  */

/* Lookup an operand by its name.
   Returns NULL if NAME is not supported by the currently selected
   mach/isa.  */

const CGEN_OPERAND *
cgen_operand_lookup_by_name (cd, name)
     CGEN_CPU_DESC cd;
     const char *name;
{
  int i;
  const CGEN_OPERAND **op = cd->operand_table.entries;

  for (i = 0; i < cd->operand_table.num_entries; ++i)
    if (op[i] && strcmp (name, op[i]->name) == 0)
      return op[i];

  return NULL;
}

/* Lookup an operand by its number.
   Operands are enumerated, however it may be possible to add some
   at runtime, thus OPNUM is not an enum type but rather an int.
   Returns NULL if OPNUM is not supported by the currently selected
   mach/isa.  */

const CGEN_OPERAND *
cgen_operand_lookup_by_num (cd, opnum)
     CGEN_CPU_DESC cd;
     int opnum;
{
  return cd->operand_table.entries[opnum];
}

/* Instruction support.  */

/* Return number of instructions.  This includes any added at runtime.  */

int
cgen_insn_count (cd)
     CGEN_CPU_DESC cd;
{
  int count = cd->insn_table.num_init_entries;
  CGEN_INSN_LIST *rt_insns = cd->insn_table.new_entries;

  for ( ; rt_insns != NULL; rt_insns = rt_insns->next)
    ++count;

  return count;
}

/* Return number of macro-instructions.
   This includes any added at runtime.  */

int
cgen_macro_insn_count (cd)
     CGEN_CPU_DESC cd;
{
  int count = cd->macro_insn_table.num_init_entries;
  CGEN_INSN_LIST *rt_insns = cd->macro_insn_table.new_entries;

  for ( ; rt_insns != NULL; rt_insns = rt_insns->next)
    ++count;

  return count;
}

/* Cover function to read and properly byteswap an insn value.  */

CGEN_INSN_INT
cgen_get_insn_value (cd, buf, length)
     CGEN_CPU_DESC cd;
     unsigned char *buf;
     int length;
{
  CGEN_INSN_INT value;

  switch (length)
    {
    case 8:
      value = *buf;
      break;
    case 16:
      if (cd->insn_endian == CGEN_ENDIAN_BIG)
	value = bfd_getb16 (buf);
      else
	value = bfd_getl16 (buf);
      break;
    case 32:
      if (cd->insn_endian == CGEN_ENDIAN_BIG)
	value = bfd_getb32 (buf);
      else
	value = bfd_getl32 (buf);
      break;
    default:
      abort ();
    }

  return value;
}

/* Cover function to store an insn value properly byteswapped.  */

void
cgen_put_insn_value (cd, buf, length, value)
     CGEN_CPU_DESC cd;
     unsigned char *buf;
     int length;
     CGEN_INSN_INT value;
{
  switch (length)
    {
    case 8:
      buf[0] = value;
      break;
    case 16:
      if (cd->insn_endian == CGEN_ENDIAN_BIG)
	bfd_putb16 (value, buf);
      else
	bfd_putl16 (value, buf);
      break;
    case 32:
      if (cd->insn_endian == CGEN_ENDIAN_BIG)
	bfd_putb32 (value, buf);
      else
	bfd_putl32 (value, buf);
      break;
    default:
      abort ();
    }
}

/* Look up instruction INSN_*_VALUE and extract its fields.
   INSN_INT_VALUE is used if CGEN_INT_INSN_P.
   Otherwise INSN_BYTES_VALUE is used.
   INSN, if non-null, is the insn table entry.
   Otherwise INSN_*_VALUE is examined to compute it.
   LENGTH is the bit length of INSN_*_VALUE if known, otherwise 0.
   0 is only valid if `insn == NULL && ! CGEN_INT_INSN_P'.
   If INSN != NULL, LENGTH must be valid.
   ALIAS_P is non-zero if alias insns are to be included in the search.

   The result is a pointer to the insn table entry, or NULL if the instruction
   wasn't recognized.  */

/* ??? Will need to be revisited for VLIW architectures.  */

const CGEN_INSN *
cgen_lookup_insn (cd, insn, insn_int_value, insn_bytes_value, length, fields,
		  alias_p)
     CGEN_CPU_DESC cd;
     const CGEN_INSN *insn;
     CGEN_INSN_INT insn_int_value;
     /* ??? CGEN_INSN_BYTES would be a nice type name to use here.  */
     unsigned char *insn_bytes_value;
     int length;
     CGEN_FIELDS *fields;
     int alias_p;
{
  unsigned char *buf;
  CGEN_INSN_INT base_insn;
  CGEN_EXTRACT_INFO ex_info;
  CGEN_EXTRACT_INFO *info;

  if (cd->int_insn_p)
    {
      info = NULL;
      buf = (unsigned char *) alloca (cd->max_insn_bitsize / 8);
      cgen_put_insn_value (cd, buf, length, insn_int_value);
      base_insn = insn_int_value;
    }
  else
    {
      info = &ex_info;
      ex_info.dis_info = NULL;
      ex_info.insn_bytes = insn_bytes_value;
      ex_info.valid = -1;
      buf = insn_bytes_value;
      base_insn = cgen_get_insn_value (cd, buf, length);
    }

  if (!insn)
    {
      const CGEN_INSN_LIST *insn_list;

      /* The instructions are stored in hash lists.
	 Pick the first one and keep trying until we find the right one.  */

      insn_list = cgen_dis_lookup_insn (cd, buf, base_insn);
      while (insn_list != NULL)
	{
	  insn = insn_list->insn;

	  if (alias_p
	      /* FIXME: Ensure ALIAS attribute always has same index.  */
	      || ! CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS))
	    {
	      /* Basic bit mask must be correct.  */
	      /* ??? May wish to allow target to defer this check until the
		 extract handler.  */
	      if ((base_insn & CGEN_INSN_BASE_MASK (insn))
		  == CGEN_INSN_BASE_VALUE (insn))
		{
		  /* ??? 0 is passed for `pc' */
		  int elength = CGEN_EXTRACT_FN (cd, insn)
		    (cd, insn, info, base_insn, fields, (bfd_vma) 0);
		  if (elength > 0)
		    {
		      /* sanity check */
		      if (length != 0 && length != elength)
			abort ();
		      return insn;
		    }
		}
	    }

	  insn_list = insn_list->next;
	}
    }
  else
    {
      /* Sanity check: can't pass an alias insn if ! alias_p.  */
      if (! alias_p
	  && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS))
	abort ();
      /* Sanity check: length must be correct.  */
      if (length != CGEN_INSN_BITSIZE (insn))
	abort ();

      /* ??? 0 is passed for `pc' */
      length = CGEN_EXTRACT_FN (cd, insn)
	(cd, insn, info, base_insn, fields, (bfd_vma) 0);
      /* Sanity check: must succeed.
	 Could relax this later if it ever proves useful.  */
      if (length == 0)
	abort ();
      return insn;
    }

  return NULL;
}

/* Fill in the operand instances used by INSN whose operands are FIELDS.
   INDICES is a pointer to a buffer of MAX_OPERAND_INSTANCES ints to be filled
   in.  */

void
cgen_get_insn_operands (cd, insn, fields, indices)
     CGEN_CPU_DESC cd;
     const CGEN_INSN *insn;
     const CGEN_FIELDS *fields;
     int *indices;
{
  const CGEN_OPINST *opinst;
  int i;

  if (insn->opinst == NULL)
    abort ();
  for (i = 0, opinst = insn->opinst; opinst->type != CGEN_OPINST_END; ++i, ++opinst)
    {
      enum cgen_operand_type op_type = opinst->op_type;
      if (op_type == CGEN_OPERAND_NIL)
	indices[i] = opinst->index;
      else
	indices[i] = (*cd->get_int_operand) (cd, op_type, fields);
    }
}

/* Cover function to cgen_get_insn_operands when either INSN or FIELDS
   isn't known.
   The INSN, INSN_*_VALUE, and LENGTH arguments are passed to
   cgen_lookup_insn unchanged.
   INSN_INT_VALUE is used if CGEN_INT_INSN_P.
   Otherwise INSN_BYTES_VALUE is used.

   The result is the insn table entry or NULL if the instruction wasn't
   recognized.  */

const CGEN_INSN *
cgen_lookup_get_insn_operands (cd, insn, insn_int_value, insn_bytes_value,
			       length, indices, fields)
     CGEN_CPU_DESC cd;
     const CGEN_INSN *insn;
     CGEN_INSN_INT insn_int_value;
     /* ??? CGEN_INSN_BYTES would be a nice type name to use here.  */
     unsigned char *insn_bytes_value;
     int length;
     int *indices;
     CGEN_FIELDS *fields;
{
  /* Pass non-zero for ALIAS_P only if INSN != NULL.
     If INSN == NULL, we want a real insn.  */
  insn = cgen_lookup_insn (cd, insn, insn_int_value, insn_bytes_value,
			   length, fields, insn != NULL);
  if (! insn)
    return NULL;

  cgen_get_insn_operands (cd, insn, fields, indices);
  return insn;
}
