/* Configurable Xtensa ISA support.
   Copyright 2003 Free Software Foundation, Inc.

   This file is part of BFD, the Binary File Descriptor library.

   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 of the License, 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 <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>

#include "xtensa-isa.h"
#include "xtensa-isa-internal.h"

xtensa_isa xtensa_default_isa = NULL;

static int
opname_lookup_compare (const void *v1, const void *v2)
{
  opname_lookup_entry *e1 = (opname_lookup_entry *)v1;
  opname_lookup_entry *e2 = (opname_lookup_entry *)v2;

  return strcmp (e1->key, e2->key);
}


xtensa_isa
xtensa_isa_init (void)
{
  xtensa_isa isa;
  int mod;

  isa = xtensa_load_isa (0);
  if (isa == 0)
    {
      fprintf (stderr, "Failed to initialize Xtensa base ISA module\n");
      return NULL;
    }

  for (mod = 1; xtensa_isa_modules[mod].get_num_opcodes_fn; mod++)
    {
      if (!xtensa_extend_isa (isa, mod))
	{
	  fprintf (stderr, "Failed to initialize Xtensa TIE ISA module\n");
	  return NULL;
	}
    }

  return isa;
}

/* ISA information.  */

static int
xtensa_check_isa_config (xtensa_isa_internal *isa,
			 struct config_struct *config_table)
{
  int i, j;

  if (!config_table)
    {
      fprintf (stderr, "Error: Empty configuration table in ISA DLL\n");
      return 0;
    }

  /* For the first module, save a pointer to the table and record the
     specified endianness and availability of the density option.  */

  if (isa->num_modules == 0)
    {
      int found_memory_order = 0;

      isa->config = config_table;
      isa->has_density = 1;  /* Default to have density option.  */

      for (i = 0; config_table[i].param_name; i++)
	{
	  if (!strcmp (config_table[i].param_name, "IsaMemoryOrder"))
	    {
	      isa->is_big_endian =
		(strcmp (config_table[i].param_value, "BigEndian") == 0);
	      found_memory_order = 1;
	    }
	  if (!strcmp (config_table[i].param_name, "IsaUseDensityInstruction"))
	    {
	      isa->has_density = atoi (config_table[i].param_value);
	    }
	}
      if (!found_memory_order)
	{
	  fprintf (stderr, "Error: \"IsaMemoryOrder\" missing from "
		   "configuration table in ISA DLL\n");
	  return 0;
	}

      return 1;
    }

  /* For subsequent modules, check that the parameters match.  Note: This
     code is sufficient to handle the current model where there are never
     more than 2 modules; we might at some point want to handle cases where
     module N > 0 specifies some parameters not included in the base table,
     and we would then add those to isa->config so that subsequent modules
     would check against them. */

  for (i = 0; config_table[i].param_name; i++)
    {
      for (j = 0; isa->config[j].param_name; j++)
	{
	  if (!strcmp (config_table[i].param_name, isa->config[j].param_name))
	    {
	      int mismatch;
	      if (!strcmp (config_table[i].param_name, "IsaCoprocessorCount"))
		{
		  /* Only require the coprocessor count to be <= the base.  */
		  int tiecnt = atoi (config_table[i].param_value);
		  int basecnt = atoi (isa->config[j].param_value);
		  mismatch = (tiecnt > basecnt);
		}
	      else
		mismatch = strcmp (config_table[i].param_value,
				   isa->config[j].param_value);
	      if (mismatch)
		{
#define MISMATCH_MESSAGE \
"Error: Configuration mismatch in the \"%s\" parameter:\n\
the configuration used when the TIE file was compiled had a value of\n\
\"%s\", while the current configuration has a value of\n\
\"%s\". Please rerun the TIE compiler with a matching\n\
configuration.\n"
		  fprintf (stderr, MISMATCH_MESSAGE,
			   config_table[i].param_name,
			   config_table[i].param_value,
			   isa->config[j].param_value);
		  return 0;
		}
	      break;
	    }
	}
    }

  return 1;
}


static int
xtensa_add_isa (xtensa_isa_internal *isa, libisa_module_specifier libisa)
{
  const int (*get_num_opcodes_fn) (void);
  struct config_struct *(*get_config_table_fn) (void);
  xtensa_opcode_internal **(*get_opcodes_fn) (void);
  int (*decode_insn_fn) (const xtensa_insnbuf);
  xtensa_opcode_internal **opcodes;
  int opc, insn_size, prev_num_opcodes, new_num_opcodes, this_module;

  get_num_opcodes_fn = xtensa_isa_modules[libisa].get_num_opcodes_fn;
  get_opcodes_fn = xtensa_isa_modules[libisa].get_opcodes_fn;
  decode_insn_fn = xtensa_isa_modules[libisa].decode_insn_fn;
  get_config_table_fn = xtensa_isa_modules[libisa].get_config_table_fn;

  if (!get_num_opcodes_fn || !get_opcodes_fn || !decode_insn_fn
      || (!get_config_table_fn && isa->num_modules == 0))
    return 0;

  if (get_config_table_fn
      && !xtensa_check_isa_config (isa, get_config_table_fn ()))
    return 0;

  prev_num_opcodes = isa->num_opcodes;
  new_num_opcodes = (*get_num_opcodes_fn) ();

  isa->num_opcodes += new_num_opcodes;
  isa->opcode_table = (xtensa_opcode_internal **)
    realloc (isa->opcode_table, isa->num_opcodes *
	     sizeof (xtensa_opcode_internal *));
  isa->opname_lookup_table = (opname_lookup_entry *)
    realloc (isa->opname_lookup_table, isa->num_opcodes *
	     sizeof (opname_lookup_entry));

  opcodes = (*get_opcodes_fn) ();

  insn_size = isa->insn_size;
  for (opc = 0; opc < new_num_opcodes; opc++)
    {
      xtensa_opcode_internal *intopc = opcodes[opc];
      int newopc = prev_num_opcodes + opc;
      isa->opcode_table[newopc] = intopc;
      isa->opname_lookup_table[newopc].key = intopc->name;
      isa->opname_lookup_table[newopc].opcode = newopc;
      if (intopc->length > insn_size)
	insn_size = intopc->length;
    }

  isa->insn_size = insn_size;
  isa->insnbuf_size = ((isa->insn_size + sizeof (xtensa_insnbuf_word) - 1) /
		       sizeof (xtensa_insnbuf_word));

  qsort (isa->opname_lookup_table, isa->num_opcodes,
	 sizeof (opname_lookup_entry), opname_lookup_compare);

  /* Check for duplicate opcode names.  */
  for (opc = 1; opc < isa->num_opcodes; opc++)
    {
      if (!opname_lookup_compare (&isa->opname_lookup_table[opc-1],
				  &isa->opname_lookup_table[opc]))
	{
	  fprintf (stderr, "Error: Duplicate TIE opcode \"%s\"\n",
		   isa->opname_lookup_table[opc].key);
	  return 0;
	}
    }

  this_module = isa->num_modules;
  isa->num_modules += 1;

  isa->module_opcode_base = (int *) realloc (isa->module_opcode_base,
					     isa->num_modules * sizeof (int));
  isa->module_decode_fn = (xtensa_insn_decode_fn *)
    realloc (isa->module_decode_fn, isa->num_modules *
	     sizeof (xtensa_insn_decode_fn));

  isa->module_opcode_base[this_module] = prev_num_opcodes;
  isa->module_decode_fn[this_module] = decode_insn_fn;

  xtensa_default_isa = isa;

  return 1;	/* Library was successfully added.  */
}


xtensa_isa
xtensa_load_isa (libisa_module_specifier libisa)
{
  xtensa_isa_internal *isa;

  isa = (xtensa_isa_internal *) malloc (sizeof (xtensa_isa_internal));
  memset (isa, 0, sizeof (xtensa_isa_internal));
  if (!xtensa_add_isa (isa, libisa))
    {
      xtensa_isa_free (isa);
      return NULL;
    }
  return (xtensa_isa) isa;
}


int
xtensa_extend_isa (xtensa_isa isa, libisa_module_specifier libisa)
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  return xtensa_add_isa (intisa, libisa);
}


void
xtensa_isa_free (xtensa_isa isa)
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  if (intisa->opcode_table)
    free (intisa->opcode_table);
  if (intisa->opname_lookup_table)
    free (intisa->opname_lookup_table);
  if (intisa->module_opcode_base)
    free (intisa->module_opcode_base);
  if (intisa->module_decode_fn)
    free (intisa->module_decode_fn);
  free (intisa);
}


int
xtensa_insn_maxlength (xtensa_isa isa)
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  return intisa->insn_size;
}


int
xtensa_insnbuf_size (xtensa_isa isa)
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
  return intisa->insnbuf_size;
}


int
xtensa_num_opcodes (xtensa_isa isa)
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  return intisa->num_opcodes;
}


xtensa_opcode
xtensa_opcode_lookup (xtensa_isa isa, const char *opname)
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  opname_lookup_entry entry, *result;

  entry.key = opname;
  result = bsearch (&entry, intisa->opname_lookup_table, intisa->num_opcodes,
		    sizeof (opname_lookup_entry), opname_lookup_compare);
  if (!result) return XTENSA_UNDEFINED;
  return result->opcode;
}


xtensa_opcode
xtensa_decode_insn (xtensa_isa isa, const xtensa_insnbuf insn)
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  int n, opc;
  for (n = 0; n < intisa->num_modules; n++) {
    opc = (intisa->module_decode_fn[n]) (insn);
    if (opc != XTENSA_UNDEFINED)
      return intisa->module_opcode_base[n] + opc;
  }
  return XTENSA_UNDEFINED;
}


/* Opcode information.  */

void
xtensa_encode_insn (xtensa_isa isa, xtensa_opcode opc, xtensa_insnbuf insn)
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_insnbuf template = intisa->opcode_table[opc]->template();
  int len = intisa->opcode_table[opc]->length;
  int n;

  /* Convert length to 32-bit words.  */
  len = (len + 3) / 4;

  /* Copy the template.  */
  for (n = 0; n < len; n++)
    insn[n] = template[n];

  /* Fill any unused buffer space with zeros.  */
  for ( ; n < intisa->insnbuf_size; n++)
    insn[n] = 0;
}


const char *
xtensa_opcode_name (xtensa_isa isa, xtensa_opcode opc)
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  return intisa->opcode_table[opc]->name;
}


int
xtensa_insn_length (xtensa_isa isa, xtensa_opcode opc)
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  return intisa->opcode_table[opc]->length;
}


int
xtensa_insn_length_from_first_byte (xtensa_isa isa, char first_byte)
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  int is_density = (first_byte & (intisa->is_big_endian ? 0x80 : 0x08)) != 0;
  return (intisa->has_density && is_density ? 2 : 3);
}


int
xtensa_num_operands (xtensa_isa isa, xtensa_opcode opc)
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  return intisa->opcode_table[opc]->iclass->num_operands;
}


xtensa_operand
xtensa_get_operand (xtensa_isa isa, xtensa_opcode opc, int opnd)
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_iclass_internal *iclass = intisa->opcode_table[opc]->iclass;
  if (opnd >= iclass->num_operands)
    return NULL;
  return (xtensa_operand) iclass->operands[opnd];
}


/* Operand information.  */

char *
xtensa_operand_kind (xtensa_operand opnd)
{
  xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
  return intop->operand_kind;
}


char
xtensa_operand_inout (xtensa_operand opnd)
{
  xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
  return intop->inout;
}


uint32
xtensa_operand_get_field (xtensa_operand opnd, const xtensa_insnbuf insn)
{
  xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
  return (*intop->get_field) (insn);
}


void
xtensa_operand_set_field (xtensa_operand opnd, xtensa_insnbuf insn, uint32 val)
{
  xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
  return (*intop->set_field) (insn, val);
}


xtensa_encode_result
xtensa_operand_encode (xtensa_operand opnd, uint32 *valp)
{
  xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
  return (*intop->encode) (valp);
}


uint32
xtensa_operand_decode (xtensa_operand opnd, uint32 val)
{
  xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
  return (*intop->decode) (val);
}


int
xtensa_operand_isPCRelative (xtensa_operand opnd)
{
  xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
  return intop->isPCRelative;
}


uint32
xtensa_operand_do_reloc (xtensa_operand opnd, uint32 addr, uint32 pc)
{
  xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
  if (!intop->isPCRelative)
    return addr;
  return (*intop->do_reloc) (addr, pc);
}


uint32
xtensa_operand_undo_reloc (xtensa_operand opnd, uint32 offset, uint32 pc)
{
  xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
  if (!intop->isPCRelative)
    return offset;
  return (*intop->undo_reloc) (offset, pc);
}


/* Instruction buffers.  */

xtensa_insnbuf
xtensa_insnbuf_alloc (xtensa_isa isa)
{
  return (xtensa_insnbuf) malloc (xtensa_insnbuf_size (isa) *
				  sizeof (xtensa_insnbuf_word));
}


void
xtensa_insnbuf_free (xtensa_insnbuf buf)
{
  free( buf );
}


/* Given <byte_index>, the index of a byte in a xtensa_insnbuf, our
   internal representation of a xtensa instruction word, return the index of
   its word and the bit index of its low order byte in the xtensa_insnbuf.  */

static inline int
byte_to_word_index (int byte_index)
{
  return byte_index / sizeof (xtensa_insnbuf_word);
}


static inline int
byte_to_bit_index (int byte_index)
{
  return (byte_index & 0x3) * 8;
}


/* Copy an instruction in the 32 bit words pointed at by <insn> to characters
   pointed at by <cp>.  This is more complicated than you might think because
   we want 16 bit instructions in bytes 2,3 for big endian. This function
   allows us to specify which byte in <insn> to start with and which way to
   increment, allowing trivial implementation for both big and little endian.
   And it seems to make pretty good code for both.  */

void
xtensa_insnbuf_to_chars (xtensa_isa isa, const xtensa_insnbuf insn, char *cp)
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  int insn_size = xtensa_insn_maxlength (intisa);
  int fence_post, start, increment, i, byte_count;
  xtensa_opcode opc;

  if (intisa->is_big_endian)
    {
      start = insn_size - 1;
      increment = -1;
    }
  else
    {
      start = 0;
      increment = 1;
    }

  /* Find the opcode; do nothing if the buffer does not contain a valid
     instruction since we need to know how many bytes to copy.  */
  opc = xtensa_decode_insn (isa, insn);
  if (opc == XTENSA_UNDEFINED)
    return;

  byte_count = xtensa_insn_length (isa, opc);
  fence_post = start + (byte_count * increment);

  for (i = start; i != fence_post; i += increment, ++cp)
    {
      int word_inx = byte_to_word_index (i);
      int bit_inx = byte_to_bit_index (i);

      *cp = (insn[word_inx] >> bit_inx) & 0xff;
    }
}

/* Inward conversion from byte stream to xtensa_insnbuf.  See
   xtensa_insnbuf_to_chars for a discussion of why this is
   complicated by endianness.  */
    
void
xtensa_insnbuf_from_chars (xtensa_isa isa, xtensa_insnbuf insn, const char* cp)
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  int insn_size = xtensa_insn_maxlength (intisa);
  int fence_post, start, increment, i;

  if (intisa->is_big_endian)
    {
      start = insn_size - 1;
      increment = -1;
    }
  else
    {
      start = 0;
      increment = 1;
    }

  fence_post = start + (insn_size * increment);
  memset (insn, 0, xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));

  for ( i = start; i != fence_post; i += increment, ++cp )
    {
      int word_inx = byte_to_word_index (i);
      int bit_inx = byte_to_bit_index (i);

      insn[word_inx] |= (*cp & 0xff) << bit_inx;
    }
}

