/* CGEN generic opcode support.

   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 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"

#ifdef HAVE_ALLOCA_H
#include <alloca.h>
#endif

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;
{
  unsigned 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;
     unsigned int hwnum;
{
  unsigned 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;
{
  unsigned 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;
{
  return bfd_get_bits (buf, length, cd->insn_endian == CGEN_ENDIAN_BIG);
}

/* 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;
{
  bfd_put_bits ((bfd_vma) value, buf, length,
		cd->insn_endian == CGEN_ENDIAN_BIG);
}

/* 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;
}

/* Allow signed overflow of instruction fields.  */
void
cgen_set_signed_overflow_ok (cd)
     CGEN_CPU_DESC cd;
{
  cd->signed_overflow_ok_p = 1;
}

/* Generate an error message if a signed field in an instruction overflows.  */
void
cgen_clear_signed_overflow_ok (cd)
     CGEN_CPU_DESC cd;
{
  cd->signed_overflow_ok_p = 0;
}

/* Will an error message be generated if a signed field in an instruction overflows ? */
unsigned int
cgen_signed_overflow_ok_p (cd)
     CGEN_CPU_DESC cd;
{
  return cd->signed_overflow_ok_p;
}
