OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [bfd/] [xtensa-isa.c] - Diff between revs 827 and 840

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 827 Rev 840
/* Configurable Xtensa ISA support.
/* Configurable Xtensa ISA support.
   Copyright 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
   Copyright 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
 
 
   This file is part of BFD, the Binary File Descriptor library.
   This file is part of BFD, the Binary File Descriptor library.
 
 
   This program is free software; you can redistribute it and/or modify
   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
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.
   (at your option) any later version.
 
 
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */
   MA 02110-1301, USA.  */
 
 
#include "sysdep.h"
#include "sysdep.h"
#include "bfd.h"
#include "bfd.h"
#include "libbfd.h"
#include "libbfd.h"
#include "xtensa-isa.h"
#include "xtensa-isa.h"
#include "xtensa-isa-internal.h"
#include "xtensa-isa-internal.h"
 
 
xtensa_isa_status xtisa_errno;
xtensa_isa_status xtisa_errno;
char xtisa_error_msg[1024];
char xtisa_error_msg[1024];
 
 
 
 
xtensa_isa_status
xtensa_isa_status
xtensa_isa_errno (xtensa_isa isa __attribute__ ((unused)))
xtensa_isa_errno (xtensa_isa isa __attribute__ ((unused)))
{
{
  return xtisa_errno;
  return xtisa_errno;
}
}
 
 
 
 
char *
char *
xtensa_isa_error_msg (xtensa_isa isa __attribute__ ((unused)))
xtensa_isa_error_msg (xtensa_isa isa __attribute__ ((unused)))
{
{
  return xtisa_error_msg;
  return xtisa_error_msg;
}
}
 
 
 
 
#define CHECK_ALLOC(MEM,ERRVAL) \
#define CHECK_ALLOC(MEM,ERRVAL) \
  do { \
  do { \
    if ((MEM) == 0) \
    if ((MEM) == 0) \
      { \
      { \
        xtisa_errno = xtensa_isa_out_of_memory; \
        xtisa_errno = xtensa_isa_out_of_memory; \
        strcpy (xtisa_error_msg, "out of memory"); \
        strcpy (xtisa_error_msg, "out of memory"); \
        return (ERRVAL); \
        return (ERRVAL); \
      } \
      } \
  } while (0)
  } while (0)
 
 
#define CHECK_ALLOC_FOR_INIT(MEM,ERRVAL,ERRNO_P,ERROR_MSG_P) \
#define CHECK_ALLOC_FOR_INIT(MEM,ERRVAL,ERRNO_P,ERROR_MSG_P) \
  do { \
  do { \
    if ((MEM) == 0) \
    if ((MEM) == 0) \
      { \
      { \
        xtisa_errno = xtensa_isa_out_of_memory; \
        xtisa_errno = xtensa_isa_out_of_memory; \
        strcpy (xtisa_error_msg, "out of memory"); \
        strcpy (xtisa_error_msg, "out of memory"); \
        if (ERRNO_P) *(ERRNO_P) = xtisa_errno; \
        if (ERRNO_P) *(ERRNO_P) = xtisa_errno; \
        if (ERROR_MSG_P) *(ERROR_MSG_P) = xtisa_error_msg; \
        if (ERROR_MSG_P) *(ERROR_MSG_P) = xtisa_error_msg; \
        return (ERRVAL); \
        return (ERRVAL); \
      } \
      } \
  } while (0)
  } while (0)
 
 
 
 


/* Instruction buffers.  */
/* Instruction buffers.  */
 
 
int
int
xtensa_insnbuf_size (xtensa_isa isa)
xtensa_insnbuf_size (xtensa_isa isa)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  return intisa->insnbuf_size;
  return intisa->insnbuf_size;
}
}
 
 
 
 
xtensa_insnbuf
xtensa_insnbuf
xtensa_insnbuf_alloc (xtensa_isa isa)
xtensa_insnbuf_alloc (xtensa_isa isa)
{
{
  xtensa_insnbuf result = (xtensa_insnbuf)
  xtensa_insnbuf result = (xtensa_insnbuf)
    malloc (xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
    malloc (xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
  CHECK_ALLOC (result, 0);
  CHECK_ALLOC (result, 0);
  return result;
  return result;
}
}
 
 
 
 
void
void
xtensa_insnbuf_free (xtensa_isa isa __attribute__ ((unused)),
xtensa_insnbuf_free (xtensa_isa isa __attribute__ ((unused)),
                     xtensa_insnbuf buf)
                     xtensa_insnbuf buf)
{
{
  free (buf);
  free (buf);
}
}
 
 
 
 
/* Given <byte_index>, the index of a byte in a xtensa_insnbuf, our
/* Given <byte_index>, the index of a byte in a xtensa_insnbuf, our
   internal representation of a xtensa instruction word, return the index of
   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.  */
   its word and the bit index of its low order byte in the xtensa_insnbuf.  */
 
 
static inline int
static inline int
byte_to_word_index (int byte_index)
byte_to_word_index (int byte_index)
{
{
  return byte_index / sizeof (xtensa_insnbuf_word);
  return byte_index / sizeof (xtensa_insnbuf_word);
}
}
 
 
 
 
static inline int
static inline int
byte_to_bit_index (int byte_index)
byte_to_bit_index (int byte_index)
{
{
  return (byte_index & 0x3) * 8;
  return (byte_index & 0x3) * 8;
}
}
 
 
 
 
/* Copy an instruction in the 32-bit words pointed at by "insn" to
/* Copy an instruction in the 32-bit words pointed at by "insn" to
   characters pointed at by "cp".  This is more complicated than you
   characters pointed at by "cp".  This is more complicated than you
   might think because we want 16-bit instructions in bytes 2 & 3 for
   might think because we want 16-bit instructions in bytes 2 & 3 for
   big-endian configurations.  This function allows us to specify
   big-endian configurations.  This function allows us to specify
   which byte in "insn" to start with and which way to increment,
   which byte in "insn" to start with and which way to increment,
   allowing trivial implementation for both big- and little-endian
   allowing trivial implementation for both big- and little-endian
   configurations....and it seems to make pretty good code for
   configurations....and it seems to make pretty good code for
   both.  */
   both.  */
 
 
int
int
xtensa_insnbuf_to_chars (xtensa_isa isa,
xtensa_insnbuf_to_chars (xtensa_isa isa,
                         const xtensa_insnbuf insn,
                         const xtensa_insnbuf insn,
                         unsigned char *cp,
                         unsigned char *cp,
                         int num_chars)
                         int num_chars)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  int insn_size = xtensa_isa_maxlength (isa);
  int insn_size = xtensa_isa_maxlength (isa);
  int fence_post, start, increment, i, byte_count;
  int fence_post, start, increment, i, byte_count;
  xtensa_format fmt;
  xtensa_format fmt;
 
 
  if (num_chars == 0)
  if (num_chars == 0)
    num_chars = insn_size;
    num_chars = insn_size;
 
 
  if (intisa->is_big_endian)
  if (intisa->is_big_endian)
    {
    {
      start = insn_size - 1;
      start = insn_size - 1;
      increment = -1;
      increment = -1;
    }
    }
  else
  else
    {
    {
      start = 0;
      start = 0;
      increment = 1;
      increment = 1;
    }
    }
 
 
  /* Find the instruction format.  Do nothing if the buffer does not contain
  /* Find the instruction format.  Do nothing if the buffer does not contain
     a valid instruction since we need to know how many bytes to copy.  */
     a valid instruction since we need to know how many bytes to copy.  */
  fmt = xtensa_format_decode (isa, insn);
  fmt = xtensa_format_decode (isa, insn);
  if (fmt == XTENSA_UNDEFINED)
  if (fmt == XTENSA_UNDEFINED)
    return XTENSA_UNDEFINED;
    return XTENSA_UNDEFINED;
 
 
  byte_count = xtensa_format_length (isa, fmt);
  byte_count = xtensa_format_length (isa, fmt);
  if (byte_count == XTENSA_UNDEFINED)
  if (byte_count == XTENSA_UNDEFINED)
    return XTENSA_UNDEFINED;
    return XTENSA_UNDEFINED;
 
 
  if (byte_count > num_chars)
  if (byte_count > num_chars)
    {
    {
      xtisa_errno = xtensa_isa_buffer_overflow;
      xtisa_errno = xtensa_isa_buffer_overflow;
      strcpy (xtisa_error_msg, "output buffer too small for instruction");
      strcpy (xtisa_error_msg, "output buffer too small for instruction");
      return XTENSA_UNDEFINED;
      return XTENSA_UNDEFINED;
    }
    }
 
 
  fence_post = start + (byte_count * increment);
  fence_post = start + (byte_count * increment);
 
 
  for (i = start; i != fence_post; i += increment, ++cp)
  for (i = start; i != fence_post; i += increment, ++cp)
    {
    {
      int word_inx = byte_to_word_index (i);
      int word_inx = byte_to_word_index (i);
      int bit_inx = byte_to_bit_index (i);
      int bit_inx = byte_to_bit_index (i);
 
 
      *cp = (insn[word_inx] >> bit_inx) & 0xff;
      *cp = (insn[word_inx] >> bit_inx) & 0xff;
    }
    }
 
 
  return byte_count;
  return byte_count;
}
}
 
 
 
 
/* Inward conversion from byte stream to xtensa_insnbuf.  See
/* Inward conversion from byte stream to xtensa_insnbuf.  See
   xtensa_insnbuf_to_chars for a discussion of why this is complicated
   xtensa_insnbuf_to_chars for a discussion of why this is complicated
   by endianness.  */
   by endianness.  */
 
 
void
void
xtensa_insnbuf_from_chars (xtensa_isa isa,
xtensa_insnbuf_from_chars (xtensa_isa isa,
                           xtensa_insnbuf insn,
                           xtensa_insnbuf insn,
                           const unsigned char *cp,
                           const unsigned char *cp,
                           int num_chars)
                           int num_chars)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  int max_size, insn_size, fence_post, start, increment, i;
  int max_size, insn_size, fence_post, start, increment, i;
 
 
  max_size = xtensa_isa_maxlength (isa);
  max_size = xtensa_isa_maxlength (isa);
 
 
  /* Decode the instruction length so we know how many bytes to read.  */
  /* Decode the instruction length so we know how many bytes to read.  */
  insn_size = (intisa->length_decode_fn) (cp);
  insn_size = (intisa->length_decode_fn) (cp);
  if (insn_size == XTENSA_UNDEFINED)
  if (insn_size == XTENSA_UNDEFINED)
    {
    {
      /* This should never happen when the byte stream contains a
      /* This should never happen when the byte stream contains a
         valid instruction.  Just read the maximum number of bytes....  */
         valid instruction.  Just read the maximum number of bytes....  */
      insn_size = max_size;
      insn_size = max_size;
    }
    }
 
 
  if (num_chars == 0 || num_chars > insn_size)
  if (num_chars == 0 || num_chars > insn_size)
    num_chars = insn_size;
    num_chars = insn_size;
 
 
  if (intisa->is_big_endian)
  if (intisa->is_big_endian)
    {
    {
      start = max_size - 1;
      start = max_size - 1;
      increment = -1;
      increment = -1;
    }
    }
  else
  else
    {
    {
      start = 0;
      start = 0;
      increment = 1;
      increment = 1;
    }
    }
 
 
  fence_post = start + (num_chars * increment);
  fence_post = start + (num_chars * increment);
  memset (insn, 0, xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
  memset (insn, 0, xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
 
 
  for (i = start; i != fence_post; i += increment, ++cp)
  for (i = start; i != fence_post; i += increment, ++cp)
    {
    {
      int word_inx = byte_to_word_index (i);
      int word_inx = byte_to_word_index (i);
      int bit_inx = byte_to_bit_index (i);
      int bit_inx = byte_to_bit_index (i);
 
 
      insn[word_inx] |= (*cp & 0xff) << bit_inx;
      insn[word_inx] |= (*cp & 0xff) << bit_inx;
    }
    }
}
}
 
 
 
 


/* ISA information.  */
/* ISA information.  */
 
 
extern xtensa_isa_internal xtensa_modules;
extern xtensa_isa_internal xtensa_modules;
 
 
xtensa_isa
xtensa_isa
xtensa_isa_init (xtensa_isa_status *errno_p, char **error_msg_p)
xtensa_isa_init (xtensa_isa_status *errno_p, char **error_msg_p)
{
{
  xtensa_isa_internal *isa = &xtensa_modules;
  xtensa_isa_internal *isa = &xtensa_modules;
  int n, is_user;
  int n, is_user;
 
 
  /* Set up the opcode name lookup table.  */
  /* Set up the opcode name lookup table.  */
  isa->opname_lookup_table =
  isa->opname_lookup_table =
    bfd_malloc (isa->num_opcodes * sizeof (xtensa_lookup_entry));
    bfd_malloc (isa->num_opcodes * sizeof (xtensa_lookup_entry));
  CHECK_ALLOC_FOR_INIT (isa->opname_lookup_table, NULL, errno_p, error_msg_p);
  CHECK_ALLOC_FOR_INIT (isa->opname_lookup_table, NULL, errno_p, error_msg_p);
  for (n = 0; n < isa->num_opcodes; n++)
  for (n = 0; n < isa->num_opcodes; n++)
    {
    {
      isa->opname_lookup_table[n].key = isa->opcodes[n].name;
      isa->opname_lookup_table[n].key = isa->opcodes[n].name;
      isa->opname_lookup_table[n].u.opcode = n;
      isa->opname_lookup_table[n].u.opcode = n;
    }
    }
  qsort (isa->opname_lookup_table, isa->num_opcodes,
  qsort (isa->opname_lookup_table, isa->num_opcodes,
         sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
         sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
 
 
  /* Set up the state name lookup table.  */
  /* Set up the state name lookup table.  */
  isa->state_lookup_table =
  isa->state_lookup_table =
    bfd_malloc (isa->num_states * sizeof (xtensa_lookup_entry));
    bfd_malloc (isa->num_states * sizeof (xtensa_lookup_entry));
  CHECK_ALLOC_FOR_INIT (isa->state_lookup_table, NULL, errno_p, error_msg_p);
  CHECK_ALLOC_FOR_INIT (isa->state_lookup_table, NULL, errno_p, error_msg_p);
  for (n = 0; n < isa->num_states; n++)
  for (n = 0; n < isa->num_states; n++)
    {
    {
      isa->state_lookup_table[n].key = isa->states[n].name;
      isa->state_lookup_table[n].key = isa->states[n].name;
      isa->state_lookup_table[n].u.state = n;
      isa->state_lookup_table[n].u.state = n;
    }
    }
  qsort (isa->state_lookup_table, isa->num_states,
  qsort (isa->state_lookup_table, isa->num_states,
         sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
         sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
 
 
  /* Set up the sysreg name lookup table.  */
  /* Set up the sysreg name lookup table.  */
  isa->sysreg_lookup_table =
  isa->sysreg_lookup_table =
    bfd_malloc (isa->num_sysregs * sizeof (xtensa_lookup_entry));
    bfd_malloc (isa->num_sysregs * sizeof (xtensa_lookup_entry));
  CHECK_ALLOC_FOR_INIT (isa->sysreg_lookup_table, NULL, errno_p, error_msg_p);
  CHECK_ALLOC_FOR_INIT (isa->sysreg_lookup_table, NULL, errno_p, error_msg_p);
  for (n = 0; n < isa->num_sysregs; n++)
  for (n = 0; n < isa->num_sysregs; n++)
    {
    {
      isa->sysreg_lookup_table[n].key = isa->sysregs[n].name;
      isa->sysreg_lookup_table[n].key = isa->sysregs[n].name;
      isa->sysreg_lookup_table[n].u.sysreg = n;
      isa->sysreg_lookup_table[n].u.sysreg = n;
    }
    }
  qsort (isa->sysreg_lookup_table, isa->num_sysregs,
  qsort (isa->sysreg_lookup_table, isa->num_sysregs,
         sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
         sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
 
 
  /* Set up the user & system sysreg number tables.  */
  /* Set up the user & system sysreg number tables.  */
  for (is_user = 0; is_user < 2; is_user++)
  for (is_user = 0; is_user < 2; is_user++)
    {
    {
      isa->sysreg_table[is_user] =
      isa->sysreg_table[is_user] =
        bfd_malloc ((isa->max_sysreg_num[is_user] + 1)
        bfd_malloc ((isa->max_sysreg_num[is_user] + 1)
                    * sizeof (xtensa_sysreg));
                    * sizeof (xtensa_sysreg));
      CHECK_ALLOC_FOR_INIT (isa->sysreg_table[is_user], NULL,
      CHECK_ALLOC_FOR_INIT (isa->sysreg_table[is_user], NULL,
                            errno_p, error_msg_p);
                            errno_p, error_msg_p);
 
 
      for (n = 0; n <= isa->max_sysreg_num[is_user]; n++)
      for (n = 0; n <= isa->max_sysreg_num[is_user]; n++)
        isa->sysreg_table[is_user][n] = XTENSA_UNDEFINED;
        isa->sysreg_table[is_user][n] = XTENSA_UNDEFINED;
    }
    }
  for (n = 0; n < isa->num_sysregs; n++)
  for (n = 0; n < isa->num_sysregs; n++)
    {
    {
      xtensa_sysreg_internal *sreg = &isa->sysregs[n];
      xtensa_sysreg_internal *sreg = &isa->sysregs[n];
      is_user = sreg->is_user;
      is_user = sreg->is_user;
 
 
      isa->sysreg_table[is_user][sreg->number] = n;
      isa->sysreg_table[is_user][sreg->number] = n;
    }
    }
 
 
  /* Set up the interface lookup table.  */
  /* Set up the interface lookup table.  */
  isa->interface_lookup_table =
  isa->interface_lookup_table =
    bfd_malloc (isa->num_interfaces * sizeof (xtensa_lookup_entry));
    bfd_malloc (isa->num_interfaces * sizeof (xtensa_lookup_entry));
  CHECK_ALLOC_FOR_INIT (isa->interface_lookup_table, NULL, errno_p,
  CHECK_ALLOC_FOR_INIT (isa->interface_lookup_table, NULL, errno_p,
                        error_msg_p);
                        error_msg_p);
  for (n = 0; n < isa->num_interfaces; n++)
  for (n = 0; n < isa->num_interfaces; n++)
    {
    {
      isa->interface_lookup_table[n].key = isa->interfaces[n].name;
      isa->interface_lookup_table[n].key = isa->interfaces[n].name;
      isa->interface_lookup_table[n].u.intf = n;
      isa->interface_lookup_table[n].u.intf = n;
    }
    }
  qsort (isa->interface_lookup_table, isa->num_interfaces,
  qsort (isa->interface_lookup_table, isa->num_interfaces,
         sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
         sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
 
 
  /* Set up the funcUnit lookup table.  */
  /* Set up the funcUnit lookup table.  */
  isa->funcUnit_lookup_table =
  isa->funcUnit_lookup_table =
    bfd_malloc (isa->num_funcUnits * sizeof (xtensa_lookup_entry));
    bfd_malloc (isa->num_funcUnits * sizeof (xtensa_lookup_entry));
  CHECK_ALLOC_FOR_INIT (isa->funcUnit_lookup_table, NULL, errno_p,
  CHECK_ALLOC_FOR_INIT (isa->funcUnit_lookup_table, NULL, errno_p,
                        error_msg_p);
                        error_msg_p);
  for (n = 0; n < isa->num_funcUnits; n++)
  for (n = 0; n < isa->num_funcUnits; n++)
    {
    {
      isa->funcUnit_lookup_table[n].key = isa->funcUnits[n].name;
      isa->funcUnit_lookup_table[n].key = isa->funcUnits[n].name;
      isa->funcUnit_lookup_table[n].u.fun = n;
      isa->funcUnit_lookup_table[n].u.fun = n;
    }
    }
  qsort (isa->funcUnit_lookup_table, isa->num_funcUnits,
  qsort (isa->funcUnit_lookup_table, isa->num_funcUnits,
         sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
         sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
 
 
  isa->insnbuf_size = ((isa->insn_size + sizeof (xtensa_insnbuf_word) - 1) /
  isa->insnbuf_size = ((isa->insn_size + sizeof (xtensa_insnbuf_word) - 1) /
                       sizeof (xtensa_insnbuf_word));
                       sizeof (xtensa_insnbuf_word));
 
 
  return (xtensa_isa) isa;
  return (xtensa_isa) isa;
}
}
 
 
 
 
void
void
xtensa_isa_free (xtensa_isa isa)
xtensa_isa_free (xtensa_isa isa)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  int n;
  int n;
 
 
  /* With this version of the code, the xtensa_isa structure is not
  /* With this version of the code, the xtensa_isa structure is not
     dynamically allocated, so this function is not essential.  Free
     dynamically allocated, so this function is not essential.  Free
     the memory allocated by xtensa_isa_init and restore the xtensa_isa
     the memory allocated by xtensa_isa_init and restore the xtensa_isa
     structure to its initial state.  */
     structure to its initial state.  */
 
 
  if (intisa->opname_lookup_table)
  if (intisa->opname_lookup_table)
    {
    {
      free (intisa->opname_lookup_table);
      free (intisa->opname_lookup_table);
      intisa->opname_lookup_table = 0;
      intisa->opname_lookup_table = 0;
    }
    }
 
 
  if (intisa->state_lookup_table)
  if (intisa->state_lookup_table)
    {
    {
      free (intisa->state_lookup_table);
      free (intisa->state_lookup_table);
      intisa->state_lookup_table = 0;
      intisa->state_lookup_table = 0;
    }
    }
 
 
  if (intisa->sysreg_lookup_table)
  if (intisa->sysreg_lookup_table)
    {
    {
      free (intisa->sysreg_lookup_table);
      free (intisa->sysreg_lookup_table);
      intisa->sysreg_lookup_table = 0;
      intisa->sysreg_lookup_table = 0;
    }
    }
  for (n = 0; n < 2; n++)
  for (n = 0; n < 2; n++)
    {
    {
      if (intisa->sysreg_table[n])
      if (intisa->sysreg_table[n])
        {
        {
          free (intisa->sysreg_table[n]);
          free (intisa->sysreg_table[n]);
          intisa->sysreg_table[n] = 0;
          intisa->sysreg_table[n] = 0;
        }
        }
    }
    }
 
 
  if (intisa->interface_lookup_table)
  if (intisa->interface_lookup_table)
    {
    {
      free (intisa->interface_lookup_table);
      free (intisa->interface_lookup_table);
      intisa->interface_lookup_table = 0;
      intisa->interface_lookup_table = 0;
    }
    }
 
 
  if (intisa->funcUnit_lookup_table)
  if (intisa->funcUnit_lookup_table)
    {
    {
      free (intisa->funcUnit_lookup_table);
      free (intisa->funcUnit_lookup_table);
      intisa->funcUnit_lookup_table = 0;
      intisa->funcUnit_lookup_table = 0;
    }
    }
}
}
 
 
 
 
int
int
xtensa_isa_name_compare (const void *v1, const void *v2)
xtensa_isa_name_compare (const void *v1, const void *v2)
{
{
  xtensa_lookup_entry *e1 = (xtensa_lookup_entry *) v1;
  xtensa_lookup_entry *e1 = (xtensa_lookup_entry *) v1;
  xtensa_lookup_entry *e2 = (xtensa_lookup_entry *) v2;
  xtensa_lookup_entry *e2 = (xtensa_lookup_entry *) v2;
 
 
  return strcasecmp (e1->key, e2->key);
  return strcasecmp (e1->key, e2->key);
}
}
 
 
 
 
int
int
xtensa_isa_maxlength (xtensa_isa isa)
xtensa_isa_maxlength (xtensa_isa isa)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  return intisa->insn_size;
  return intisa->insn_size;
}
}
 
 
 
 
int
int
xtensa_isa_length_from_chars (xtensa_isa isa, const unsigned char *cp)
xtensa_isa_length_from_chars (xtensa_isa isa, const unsigned char *cp)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  return (intisa->length_decode_fn) (cp);
  return (intisa->length_decode_fn) (cp);
}
}
 
 
 
 
int
int
xtensa_isa_num_pipe_stages (xtensa_isa isa)
xtensa_isa_num_pipe_stages (xtensa_isa isa)
{
{
  xtensa_opcode opcode;
  xtensa_opcode opcode;
  xtensa_funcUnit_use *use;
  xtensa_funcUnit_use *use;
  int num_opcodes, num_uses;
  int num_opcodes, num_uses;
  int i, stage;
  int i, stage;
  static int max_stage = XTENSA_UNDEFINED;
  static int max_stage = XTENSA_UNDEFINED;
 
 
  /* Only compute the value once.  */
  /* Only compute the value once.  */
  if (max_stage != XTENSA_UNDEFINED)
  if (max_stage != XTENSA_UNDEFINED)
    return max_stage + 1;
    return max_stage + 1;
 
 
  num_opcodes = xtensa_isa_num_opcodes (isa);
  num_opcodes = xtensa_isa_num_opcodes (isa);
  for (opcode = 0; opcode < num_opcodes; opcode++)
  for (opcode = 0; opcode < num_opcodes; opcode++)
    {
    {
      num_uses = xtensa_opcode_num_funcUnit_uses (isa, opcode);
      num_uses = xtensa_opcode_num_funcUnit_uses (isa, opcode);
      for (i = 0; i < num_uses; i++)
      for (i = 0; i < num_uses; i++)
        {
        {
          use = xtensa_opcode_funcUnit_use (isa, opcode, i);
          use = xtensa_opcode_funcUnit_use (isa, opcode, i);
          stage = use->stage;
          stage = use->stage;
          if (stage > max_stage)
          if (stage > max_stage)
            max_stage = stage;
            max_stage = stage;
        }
        }
    }
    }
 
 
  return max_stage + 1;
  return max_stage + 1;
}
}
 
 
 
 
int
int
xtensa_isa_num_formats (xtensa_isa isa)
xtensa_isa_num_formats (xtensa_isa isa)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  return intisa->num_formats;
  return intisa->num_formats;
}
}
 
 
 
 
int
int
xtensa_isa_num_opcodes (xtensa_isa isa)
xtensa_isa_num_opcodes (xtensa_isa isa)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  return intisa->num_opcodes;
  return intisa->num_opcodes;
}
}
 
 
 
 
int
int
xtensa_isa_num_regfiles (xtensa_isa isa)
xtensa_isa_num_regfiles (xtensa_isa isa)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  return intisa->num_regfiles;
  return intisa->num_regfiles;
}
}
 
 
 
 
int
int
xtensa_isa_num_states (xtensa_isa isa)
xtensa_isa_num_states (xtensa_isa isa)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  return intisa->num_states;
  return intisa->num_states;
}
}
 
 
 
 
int
int
xtensa_isa_num_sysregs (xtensa_isa isa)
xtensa_isa_num_sysregs (xtensa_isa isa)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  return intisa->num_sysregs;
  return intisa->num_sysregs;
}
}
 
 
 
 
int
int
xtensa_isa_num_interfaces (xtensa_isa isa)
xtensa_isa_num_interfaces (xtensa_isa isa)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  return intisa->num_interfaces;
  return intisa->num_interfaces;
}
}
 
 
 
 
int
int
xtensa_isa_num_funcUnits (xtensa_isa isa)
xtensa_isa_num_funcUnits (xtensa_isa isa)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  return intisa->num_funcUnits;
  return intisa->num_funcUnits;
}
}
 
 
 
 


/* Instruction formats.  */
/* Instruction formats.  */
 
 
 
 
#define CHECK_FORMAT(INTISA,FMT,ERRVAL) \
#define CHECK_FORMAT(INTISA,FMT,ERRVAL) \
  do { \
  do { \
    if ((FMT) < 0 || (FMT) >= (INTISA)->num_formats) \
    if ((FMT) < 0 || (FMT) >= (INTISA)->num_formats) \
      { \
      { \
        xtisa_errno = xtensa_isa_bad_format; \
        xtisa_errno = xtensa_isa_bad_format; \
        strcpy (xtisa_error_msg, "invalid format specifier"); \
        strcpy (xtisa_error_msg, "invalid format specifier"); \
        return (ERRVAL); \
        return (ERRVAL); \
      } \
      } \
  } while (0)
  } while (0)
 
 
 
 
#define CHECK_SLOT(INTISA,FMT,SLOT,ERRVAL) \
#define CHECK_SLOT(INTISA,FMT,SLOT,ERRVAL) \
  do { \
  do { \
    if ((SLOT) < 0 || (SLOT) >= (INTISA)->formats[FMT].num_slots) \
    if ((SLOT) < 0 || (SLOT) >= (INTISA)->formats[FMT].num_slots) \
      { \
      { \
        xtisa_errno = xtensa_isa_bad_slot; \
        xtisa_errno = xtensa_isa_bad_slot; \
        strcpy (xtisa_error_msg, "invalid slot specifier"); \
        strcpy (xtisa_error_msg, "invalid slot specifier"); \
        return (ERRVAL); \
        return (ERRVAL); \
      } \
      } \
  } while (0)
  } while (0)
 
 
 
 
const char *
const char *
xtensa_format_name (xtensa_isa isa, xtensa_format fmt)
xtensa_format_name (xtensa_isa isa, xtensa_format fmt)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_FORMAT (intisa, fmt, NULL);
  CHECK_FORMAT (intisa, fmt, NULL);
  return intisa->formats[fmt].name;
  return intisa->formats[fmt].name;
}
}
 
 
 
 
xtensa_format
xtensa_format
xtensa_format_lookup (xtensa_isa isa, const char *fmtname)
xtensa_format_lookup (xtensa_isa isa, const char *fmtname)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  int fmt;
  int fmt;
 
 
  if (!fmtname || !*fmtname)
  if (!fmtname || !*fmtname)
    {
    {
      xtisa_errno = xtensa_isa_bad_format;
      xtisa_errno = xtensa_isa_bad_format;
      strcpy (xtisa_error_msg, "invalid format name");
      strcpy (xtisa_error_msg, "invalid format name");
      return XTENSA_UNDEFINED;
      return XTENSA_UNDEFINED;
    }
    }
 
 
  for (fmt = 0; fmt < intisa->num_formats; fmt++)
  for (fmt = 0; fmt < intisa->num_formats; fmt++)
    {
    {
      if (strcasecmp (fmtname, intisa->formats[fmt].name) == 0)
      if (strcasecmp (fmtname, intisa->formats[fmt].name) == 0)
        return fmt;
        return fmt;
    }
    }
 
 
  xtisa_errno = xtensa_isa_bad_format;
  xtisa_errno = xtensa_isa_bad_format;
  sprintf (xtisa_error_msg, "format \"%s\" not recognized", fmtname);
  sprintf (xtisa_error_msg, "format \"%s\" not recognized", fmtname);
  return XTENSA_UNDEFINED;
  return XTENSA_UNDEFINED;
}
}
 
 
 
 
xtensa_format
xtensa_format
xtensa_format_decode (xtensa_isa isa, const xtensa_insnbuf insn)
xtensa_format_decode (xtensa_isa isa, const xtensa_insnbuf insn)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_format fmt;
  xtensa_format fmt;
 
 
  fmt = (intisa->format_decode_fn) (insn);
  fmt = (intisa->format_decode_fn) (insn);
  if (fmt != XTENSA_UNDEFINED)
  if (fmt != XTENSA_UNDEFINED)
    return fmt;
    return fmt;
 
 
  xtisa_errno = xtensa_isa_bad_format;
  xtisa_errno = xtensa_isa_bad_format;
  strcpy (xtisa_error_msg, "cannot decode instruction format");
  strcpy (xtisa_error_msg, "cannot decode instruction format");
  return XTENSA_UNDEFINED;
  return XTENSA_UNDEFINED;
}
}
 
 
 
 
int
int
xtensa_format_encode (xtensa_isa isa, xtensa_format fmt, xtensa_insnbuf insn)
xtensa_format_encode (xtensa_isa isa, xtensa_format fmt, xtensa_insnbuf insn)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_FORMAT (intisa, fmt, -1);
  CHECK_FORMAT (intisa, fmt, -1);
  (*intisa->formats[fmt].encode_fn) (insn);
  (*intisa->formats[fmt].encode_fn) (insn);
  return 0;
  return 0;
}
}
 
 
 
 
int
int
xtensa_format_length (xtensa_isa isa, xtensa_format fmt)
xtensa_format_length (xtensa_isa isa, xtensa_format fmt)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
  CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
  return intisa->formats[fmt].length;
  return intisa->formats[fmt].length;
}
}
 
 
 
 
int
int
xtensa_format_num_slots (xtensa_isa isa, xtensa_format fmt)
xtensa_format_num_slots (xtensa_isa isa, xtensa_format fmt)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
  CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
  return intisa->formats[fmt].num_slots;
  return intisa->formats[fmt].num_slots;
}
}
 
 
 
 
xtensa_opcode
xtensa_opcode
xtensa_format_slot_nop_opcode (xtensa_isa isa, xtensa_format fmt, int slot)
xtensa_format_slot_nop_opcode (xtensa_isa isa, xtensa_format fmt, int slot)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  int slot_id;
  int slot_id;
 
 
  CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
  CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
  CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED);
  CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED);
 
 
  slot_id = intisa->formats[fmt].slot_id[slot];
  slot_id = intisa->formats[fmt].slot_id[slot];
  return xtensa_opcode_lookup (isa, intisa->slots[slot_id].nop_name);
  return xtensa_opcode_lookup (isa, intisa->slots[slot_id].nop_name);
}
}
 
 
 
 
int
int
xtensa_format_get_slot (xtensa_isa isa, xtensa_format fmt, int slot,
xtensa_format_get_slot (xtensa_isa isa, xtensa_format fmt, int slot,
                        const xtensa_insnbuf insn, xtensa_insnbuf slotbuf)
                        const xtensa_insnbuf insn, xtensa_insnbuf slotbuf)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  int slot_id;
  int slot_id;
 
 
  CHECK_FORMAT (intisa, fmt, -1);
  CHECK_FORMAT (intisa, fmt, -1);
  CHECK_SLOT (intisa, fmt, slot, -1);
  CHECK_SLOT (intisa, fmt, slot, -1);
 
 
  slot_id = intisa->formats[fmt].slot_id[slot];
  slot_id = intisa->formats[fmt].slot_id[slot];
  (*intisa->slots[slot_id].get_fn) (insn, slotbuf);
  (*intisa->slots[slot_id].get_fn) (insn, slotbuf);
  return 0;
  return 0;
}
}
 
 
 
 
int
int
xtensa_format_set_slot (xtensa_isa isa, xtensa_format fmt, int slot,
xtensa_format_set_slot (xtensa_isa isa, xtensa_format fmt, int slot,
                        xtensa_insnbuf insn, const xtensa_insnbuf slotbuf)
                        xtensa_insnbuf insn, const xtensa_insnbuf slotbuf)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  int slot_id;
  int slot_id;
 
 
  CHECK_FORMAT (intisa, fmt, -1);
  CHECK_FORMAT (intisa, fmt, -1);
  CHECK_SLOT (intisa, fmt, slot, -1);
  CHECK_SLOT (intisa, fmt, slot, -1);
 
 
  slot_id = intisa->formats[fmt].slot_id[slot];
  slot_id = intisa->formats[fmt].slot_id[slot];
  (*intisa->slots[slot_id].set_fn) (insn, slotbuf);
  (*intisa->slots[slot_id].set_fn) (insn, slotbuf);
  return 0;
  return 0;
}
}
 
 
 
 


/* Opcode information.  */
/* Opcode information.  */
 
 
 
 
#define CHECK_OPCODE(INTISA,OPC,ERRVAL) \
#define CHECK_OPCODE(INTISA,OPC,ERRVAL) \
  do { \
  do { \
    if ((OPC) < 0 || (OPC) >= (INTISA)->num_opcodes) \
    if ((OPC) < 0 || (OPC) >= (INTISA)->num_opcodes) \
      { \
      { \
        xtisa_errno = xtensa_isa_bad_opcode; \
        xtisa_errno = xtensa_isa_bad_opcode; \
        strcpy (xtisa_error_msg, "invalid opcode specifier"); \
        strcpy (xtisa_error_msg, "invalid opcode specifier"); \
        return (ERRVAL); \
        return (ERRVAL); \
      } \
      } \
  } while (0)
  } while (0)
 
 
 
 
xtensa_opcode
xtensa_opcode
xtensa_opcode_lookup (xtensa_isa isa, const char *opname)
xtensa_opcode_lookup (xtensa_isa isa, const char *opname)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_lookup_entry entry, *result = 0;
  xtensa_lookup_entry entry, *result = 0;
 
 
  if (!opname || !*opname)
  if (!opname || !*opname)
    {
    {
      xtisa_errno = xtensa_isa_bad_opcode;
      xtisa_errno = xtensa_isa_bad_opcode;
      strcpy (xtisa_error_msg, "invalid opcode name");
      strcpy (xtisa_error_msg, "invalid opcode name");
      return XTENSA_UNDEFINED;
      return XTENSA_UNDEFINED;
    }
    }
 
 
  if (intisa->num_opcodes != 0)
  if (intisa->num_opcodes != 0)
    {
    {
      entry.key = opname;
      entry.key = opname;
      result = bsearch (&entry, intisa->opname_lookup_table,
      result = bsearch (&entry, intisa->opname_lookup_table,
                        intisa->num_opcodes, sizeof (xtensa_lookup_entry),
                        intisa->num_opcodes, sizeof (xtensa_lookup_entry),
                        xtensa_isa_name_compare);
                        xtensa_isa_name_compare);
    }
    }
 
 
  if (!result)
  if (!result)
    {
    {
      xtisa_errno = xtensa_isa_bad_opcode;
      xtisa_errno = xtensa_isa_bad_opcode;
      sprintf (xtisa_error_msg, "opcode \"%s\" not recognized", opname);
      sprintf (xtisa_error_msg, "opcode \"%s\" not recognized", opname);
      return XTENSA_UNDEFINED;
      return XTENSA_UNDEFINED;
    }
    }
 
 
  return result->u.opcode;
  return result->u.opcode;
}
}
 
 
 
 
xtensa_opcode
xtensa_opcode
xtensa_opcode_decode (xtensa_isa isa, xtensa_format fmt, int slot,
xtensa_opcode_decode (xtensa_isa isa, xtensa_format fmt, int slot,
                      const xtensa_insnbuf slotbuf)
                      const xtensa_insnbuf slotbuf)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  int slot_id;
  int slot_id;
  xtensa_opcode opc;
  xtensa_opcode opc;
 
 
  CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
  CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
  CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED);
  CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED);
 
 
  slot_id = intisa->formats[fmt].slot_id[slot];
  slot_id = intisa->formats[fmt].slot_id[slot];
 
 
  opc = (intisa->slots[slot_id].opcode_decode_fn) (slotbuf);
  opc = (intisa->slots[slot_id].opcode_decode_fn) (slotbuf);
  if (opc != XTENSA_UNDEFINED)
  if (opc != XTENSA_UNDEFINED)
    return opc;
    return opc;
 
 
  xtisa_errno = xtensa_isa_bad_opcode;
  xtisa_errno = xtensa_isa_bad_opcode;
  strcpy (xtisa_error_msg, "cannot decode opcode");
  strcpy (xtisa_error_msg, "cannot decode opcode");
  return XTENSA_UNDEFINED;
  return XTENSA_UNDEFINED;
}
}
 
 
 
 
int
int
xtensa_opcode_encode (xtensa_isa isa, xtensa_format fmt, int slot,
xtensa_opcode_encode (xtensa_isa isa, xtensa_format fmt, int slot,
                      xtensa_insnbuf slotbuf, xtensa_opcode opc)
                      xtensa_insnbuf slotbuf, xtensa_opcode opc)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  int slot_id;
  int slot_id;
  xtensa_opcode_encode_fn encode_fn;
  xtensa_opcode_encode_fn encode_fn;
 
 
  CHECK_FORMAT (intisa, fmt, -1);
  CHECK_FORMAT (intisa, fmt, -1);
  CHECK_SLOT (intisa, fmt, slot, -1);
  CHECK_SLOT (intisa, fmt, slot, -1);
  CHECK_OPCODE (intisa, opc, -1);
  CHECK_OPCODE (intisa, opc, -1);
 
 
  slot_id = intisa->formats[fmt].slot_id[slot];
  slot_id = intisa->formats[fmt].slot_id[slot];
  encode_fn = intisa->opcodes[opc].encode_fns[slot_id];
  encode_fn = intisa->opcodes[opc].encode_fns[slot_id];
  if (!encode_fn)
  if (!encode_fn)
    {
    {
      xtisa_errno = xtensa_isa_wrong_slot;
      xtisa_errno = xtensa_isa_wrong_slot;
      sprintf (xtisa_error_msg,
      sprintf (xtisa_error_msg,
               "opcode \"%s\" is not allowed in slot %d of format \"%s\"",
               "opcode \"%s\" is not allowed in slot %d of format \"%s\"",
               intisa->opcodes[opc].name, slot, intisa->formats[fmt].name);
               intisa->opcodes[opc].name, slot, intisa->formats[fmt].name);
      return -1;
      return -1;
    }
    }
  (*encode_fn) (slotbuf);
  (*encode_fn) (slotbuf);
  return 0;
  return 0;
}
}
 
 
 
 
const char *
const char *
xtensa_opcode_name (xtensa_isa isa, xtensa_opcode opc)
xtensa_opcode_name (xtensa_isa isa, xtensa_opcode opc)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_OPCODE (intisa, opc, NULL);
  CHECK_OPCODE (intisa, opc, NULL);
  return intisa->opcodes[opc].name;
  return intisa->opcodes[opc].name;
}
}
 
 
 
 
int
int
xtensa_opcode_is_branch (xtensa_isa isa, xtensa_opcode opc)
xtensa_opcode_is_branch (xtensa_isa isa, xtensa_opcode opc)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_BRANCH) != 0)
  if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_BRANCH) != 0)
    return 1;
    return 1;
  return 0;
  return 0;
}
}
 
 
 
 
int
int
xtensa_opcode_is_jump (xtensa_isa isa, xtensa_opcode opc)
xtensa_opcode_is_jump (xtensa_isa isa, xtensa_opcode opc)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_JUMP) != 0)
  if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_JUMP) != 0)
    return 1;
    return 1;
  return 0;
  return 0;
}
}
 
 
 
 
int
int
xtensa_opcode_is_loop (xtensa_isa isa, xtensa_opcode opc)
xtensa_opcode_is_loop (xtensa_isa isa, xtensa_opcode opc)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_LOOP) != 0)
  if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_LOOP) != 0)
    return 1;
    return 1;
  return 0;
  return 0;
}
}
 
 
 
 
int
int
xtensa_opcode_is_call (xtensa_isa isa, xtensa_opcode opc)
xtensa_opcode_is_call (xtensa_isa isa, xtensa_opcode opc)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_CALL) != 0)
  if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_CALL) != 0)
    return 1;
    return 1;
  return 0;
  return 0;
}
}
 
 
 
 
int
int
xtensa_opcode_num_operands (xtensa_isa isa, xtensa_opcode opc)
xtensa_opcode_num_operands (xtensa_isa isa, xtensa_opcode opc)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  int iclass_id;
  int iclass_id;
 
 
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  iclass_id = intisa->opcodes[opc].iclass_id;
  iclass_id = intisa->opcodes[opc].iclass_id;
  return intisa->iclasses[iclass_id].num_operands;
  return intisa->iclasses[iclass_id].num_operands;
}
}
 
 
 
 
int
int
xtensa_opcode_num_stateOperands (xtensa_isa isa, xtensa_opcode opc)
xtensa_opcode_num_stateOperands (xtensa_isa isa, xtensa_opcode opc)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  int iclass_id;
  int iclass_id;
 
 
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  iclass_id = intisa->opcodes[opc].iclass_id;
  iclass_id = intisa->opcodes[opc].iclass_id;
  return intisa->iclasses[iclass_id].num_stateOperands;
  return intisa->iclasses[iclass_id].num_stateOperands;
}
}
 
 
 
 
int
int
xtensa_opcode_num_interfaceOperands (xtensa_isa isa, xtensa_opcode opc)
xtensa_opcode_num_interfaceOperands (xtensa_isa isa, xtensa_opcode opc)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  int iclass_id;
  int iclass_id;
 
 
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  iclass_id = intisa->opcodes[opc].iclass_id;
  iclass_id = intisa->opcodes[opc].iclass_id;
  return intisa->iclasses[iclass_id].num_interfaceOperands;
  return intisa->iclasses[iclass_id].num_interfaceOperands;
}
}
 
 
 
 
int
int
xtensa_opcode_num_funcUnit_uses (xtensa_isa isa, xtensa_opcode opc)
xtensa_opcode_num_funcUnit_uses (xtensa_isa isa, xtensa_opcode opc)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  return intisa->opcodes[opc].num_funcUnit_uses;
  return intisa->opcodes[opc].num_funcUnit_uses;
}
}
 
 
 
 
xtensa_funcUnit_use *
xtensa_funcUnit_use *
xtensa_opcode_funcUnit_use (xtensa_isa isa, xtensa_opcode opc, int u)
xtensa_opcode_funcUnit_use (xtensa_isa isa, xtensa_opcode opc, int u)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_OPCODE (intisa, opc, NULL);
  CHECK_OPCODE (intisa, opc, NULL);
  if (u < 0 || u >= intisa->opcodes[opc].num_funcUnit_uses)
  if (u < 0 || u >= intisa->opcodes[opc].num_funcUnit_uses)
    {
    {
      xtisa_errno = xtensa_isa_bad_funcUnit;
      xtisa_errno = xtensa_isa_bad_funcUnit;
      sprintf (xtisa_error_msg, "invalid functional unit use number (%d); "
      sprintf (xtisa_error_msg, "invalid functional unit use number (%d); "
               "opcode \"%s\" has %d", u, intisa->opcodes[opc].name,
               "opcode \"%s\" has %d", u, intisa->opcodes[opc].name,
               intisa->opcodes[opc].num_funcUnit_uses);
               intisa->opcodes[opc].num_funcUnit_uses);
      return NULL;
      return NULL;
    }
    }
  return &intisa->opcodes[opc].funcUnit_uses[u];
  return &intisa->opcodes[opc].funcUnit_uses[u];
}
}
 
 
 
 


/* Operand information.  */
/* Operand information.  */
 
 
 
 
#define CHECK_OPERAND(INTISA,OPC,ICLASS,OPND,ERRVAL) \
#define CHECK_OPERAND(INTISA,OPC,ICLASS,OPND,ERRVAL) \
  do { \
  do { \
    if ((OPND) < 0 || (OPND) >= (ICLASS)->num_operands) \
    if ((OPND) < 0 || (OPND) >= (ICLASS)->num_operands) \
      { \
      { \
        xtisa_errno = xtensa_isa_bad_operand; \
        xtisa_errno = xtensa_isa_bad_operand; \
        sprintf (xtisa_error_msg, "invalid operand number (%d); " \
        sprintf (xtisa_error_msg, "invalid operand number (%d); " \
                 "opcode \"%s\" has %d operands", (OPND), \
                 "opcode \"%s\" has %d operands", (OPND), \
                 (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_operands); \
                 (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_operands); \
        return (ERRVAL); \
        return (ERRVAL); \
      } \
      } \
  } while (0)
  } while (0)
 
 
 
 
static xtensa_operand_internal *
static xtensa_operand_internal *
get_operand (xtensa_isa_internal *intisa, xtensa_opcode opc, int opnd)
get_operand (xtensa_isa_internal *intisa, xtensa_opcode opc, int opnd)
{
{
  xtensa_iclass_internal *iclass;
  xtensa_iclass_internal *iclass;
  int iclass_id, operand_id;
  int iclass_id, operand_id;
 
 
  CHECK_OPCODE (intisa, opc, NULL);
  CHECK_OPCODE (intisa, opc, NULL);
  iclass_id = intisa->opcodes[opc].iclass_id;
  iclass_id = intisa->opcodes[opc].iclass_id;
  iclass = &intisa->iclasses[iclass_id];
  iclass = &intisa->iclasses[iclass_id];
  CHECK_OPERAND (intisa, opc, iclass, opnd, NULL);
  CHECK_OPERAND (intisa, opc, iclass, opnd, NULL);
  operand_id = iclass->operands[opnd].u.operand_id;
  operand_id = iclass->operands[opnd].u.operand_id;
  return &intisa->operands[operand_id];
  return &intisa->operands[operand_id];
}
}
 
 
 
 
const char *
const char *
xtensa_operand_name (xtensa_isa isa, xtensa_opcode opc, int opnd)
xtensa_operand_name (xtensa_isa isa, xtensa_opcode opc, int opnd)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_operand_internal *intop;
  xtensa_operand_internal *intop;
 
 
  intop = get_operand (intisa, opc, opnd);
  intop = get_operand (intisa, opc, opnd);
  if (!intop) return NULL;
  if (!intop) return NULL;
  return intop->name;
  return intop->name;
}
}
 
 
 
 
int
int
xtensa_operand_is_visible (xtensa_isa isa, xtensa_opcode opc, int opnd)
xtensa_operand_is_visible (xtensa_isa isa, xtensa_opcode opc, int opnd)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_iclass_internal *iclass;
  xtensa_iclass_internal *iclass;
  int iclass_id, operand_id;
  int iclass_id, operand_id;
  xtensa_operand_internal *intop;
  xtensa_operand_internal *intop;
 
 
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  iclass_id = intisa->opcodes[opc].iclass_id;
  iclass_id = intisa->opcodes[opc].iclass_id;
  iclass = &intisa->iclasses[iclass_id];
  iclass = &intisa->iclasses[iclass_id];
  CHECK_OPERAND (intisa, opc, iclass, opnd, XTENSA_UNDEFINED);
  CHECK_OPERAND (intisa, opc, iclass, opnd, XTENSA_UNDEFINED);
 
 
  /* Special case for "sout" operands.  */
  /* Special case for "sout" operands.  */
  if (iclass->operands[opnd].inout == 's')
  if (iclass->operands[opnd].inout == 's')
    return 0;
    return 0;
 
 
  operand_id = iclass->operands[opnd].u.operand_id;
  operand_id = iclass->operands[opnd].u.operand_id;
  intop = &intisa->operands[operand_id];
  intop = &intisa->operands[operand_id];
 
 
  if ((intop->flags & XTENSA_OPERAND_IS_INVISIBLE) == 0)
  if ((intop->flags & XTENSA_OPERAND_IS_INVISIBLE) == 0)
    return 1;
    return 1;
  return 0;
  return 0;
}
}
 
 
 
 
char
char
xtensa_operand_inout (xtensa_isa isa, xtensa_opcode opc, int opnd)
xtensa_operand_inout (xtensa_isa isa, xtensa_opcode opc, int opnd)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_iclass_internal *iclass;
  xtensa_iclass_internal *iclass;
  int iclass_id;
  int iclass_id;
  char inout;
  char inout;
 
 
  CHECK_OPCODE (intisa, opc, 0);
  CHECK_OPCODE (intisa, opc, 0);
  iclass_id = intisa->opcodes[opc].iclass_id;
  iclass_id = intisa->opcodes[opc].iclass_id;
  iclass = &intisa->iclasses[iclass_id];
  iclass = &intisa->iclasses[iclass_id];
  CHECK_OPERAND (intisa, opc, iclass, opnd, 0);
  CHECK_OPERAND (intisa, opc, iclass, opnd, 0);
  inout = iclass->operands[opnd].inout;
  inout = iclass->operands[opnd].inout;
 
 
  /* Special case for "sout" operands.  */
  /* Special case for "sout" operands.  */
  if (inout == 's')
  if (inout == 's')
    return 'o';
    return 'o';
 
 
  return inout;
  return inout;
}
}
 
 
 
 
int
int
xtensa_operand_get_field (xtensa_isa isa, xtensa_opcode opc, int opnd,
xtensa_operand_get_field (xtensa_isa isa, xtensa_opcode opc, int opnd,
                          xtensa_format fmt, int slot,
                          xtensa_format fmt, int slot,
                          const xtensa_insnbuf slotbuf, uint32 *valp)
                          const xtensa_insnbuf slotbuf, uint32 *valp)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_operand_internal *intop;
  xtensa_operand_internal *intop;
  int slot_id;
  int slot_id;
  xtensa_get_field_fn get_fn;
  xtensa_get_field_fn get_fn;
 
 
  intop = get_operand (intisa, opc, opnd);
  intop = get_operand (intisa, opc, opnd);
  if (!intop) return -1;
  if (!intop) return -1;
 
 
  CHECK_FORMAT (intisa, fmt, -1);
  CHECK_FORMAT (intisa, fmt, -1);
  CHECK_SLOT (intisa, fmt, slot, -1);
  CHECK_SLOT (intisa, fmt, slot, -1);
 
 
  slot_id = intisa->formats[fmt].slot_id[slot];
  slot_id = intisa->formats[fmt].slot_id[slot];
  if (intop->field_id == XTENSA_UNDEFINED)
  if (intop->field_id == XTENSA_UNDEFINED)
    {
    {
      xtisa_errno = xtensa_isa_no_field;
      xtisa_errno = xtensa_isa_no_field;
      strcpy (xtisa_error_msg, "implicit operand has no field");
      strcpy (xtisa_error_msg, "implicit operand has no field");
      return -1;
      return -1;
    }
    }
  get_fn = intisa->slots[slot_id].get_field_fns[intop->field_id];
  get_fn = intisa->slots[slot_id].get_field_fns[intop->field_id];
  if (!get_fn)
  if (!get_fn)
    {
    {
      xtisa_errno = xtensa_isa_wrong_slot;
      xtisa_errno = xtensa_isa_wrong_slot;
      sprintf (xtisa_error_msg,
      sprintf (xtisa_error_msg,
               "operand \"%s\" does not exist in slot %d of format \"%s\"",
               "operand \"%s\" does not exist in slot %d of format \"%s\"",
               intop->name, slot, intisa->formats[fmt].name);
               intop->name, slot, intisa->formats[fmt].name);
      return -1;
      return -1;
    }
    }
  *valp = (*get_fn) (slotbuf);
  *valp = (*get_fn) (slotbuf);
  return 0;
  return 0;
}
}
 
 
 
 
int
int
xtensa_operand_set_field (xtensa_isa isa, xtensa_opcode opc, int opnd,
xtensa_operand_set_field (xtensa_isa isa, xtensa_opcode opc, int opnd,
                          xtensa_format fmt, int slot,
                          xtensa_format fmt, int slot,
                          xtensa_insnbuf slotbuf, uint32 val)
                          xtensa_insnbuf slotbuf, uint32 val)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_operand_internal *intop;
  xtensa_operand_internal *intop;
  int slot_id;
  int slot_id;
  xtensa_set_field_fn set_fn;
  xtensa_set_field_fn set_fn;
 
 
  intop = get_operand (intisa, opc, opnd);
  intop = get_operand (intisa, opc, opnd);
  if (!intop) return -1;
  if (!intop) return -1;
 
 
  CHECK_FORMAT (intisa, fmt, -1);
  CHECK_FORMAT (intisa, fmt, -1);
  CHECK_SLOT (intisa, fmt, slot, -1);
  CHECK_SLOT (intisa, fmt, slot, -1);
 
 
  slot_id = intisa->formats[fmt].slot_id[slot];
  slot_id = intisa->formats[fmt].slot_id[slot];
  if (intop->field_id == XTENSA_UNDEFINED)
  if (intop->field_id == XTENSA_UNDEFINED)
    {
    {
      xtisa_errno = xtensa_isa_no_field;
      xtisa_errno = xtensa_isa_no_field;
      strcpy (xtisa_error_msg, "implicit operand has no field");
      strcpy (xtisa_error_msg, "implicit operand has no field");
      return -1;
      return -1;
    }
    }
  set_fn = intisa->slots[slot_id].set_field_fns[intop->field_id];
  set_fn = intisa->slots[slot_id].set_field_fns[intop->field_id];
  if (!set_fn)
  if (!set_fn)
    {
    {
      xtisa_errno = xtensa_isa_wrong_slot;
      xtisa_errno = xtensa_isa_wrong_slot;
      sprintf (xtisa_error_msg,
      sprintf (xtisa_error_msg,
               "operand \"%s\" does not exist in slot %d of format \"%s\"",
               "operand \"%s\" does not exist in slot %d of format \"%s\"",
               intop->name, slot, intisa->formats[fmt].name);
               intop->name, slot, intisa->formats[fmt].name);
      return -1;
      return -1;
    }
    }
  (*set_fn) (slotbuf, val);
  (*set_fn) (slotbuf, val);
  return 0;
  return 0;
}
}
 
 
 
 
int
int
xtensa_operand_encode (xtensa_isa isa, xtensa_opcode opc, int opnd,
xtensa_operand_encode (xtensa_isa isa, xtensa_opcode opc, int opnd,
                       uint32 *valp)
                       uint32 *valp)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_operand_internal *intop;
  xtensa_operand_internal *intop;
  uint32 test_val, orig_val;
  uint32 test_val, orig_val;
 
 
  intop = get_operand (intisa, opc, opnd);
  intop = get_operand (intisa, opc, opnd);
  if (!intop) return -1;
  if (!intop) return -1;
 
 
  if (!intop->encode)
  if (!intop->encode)
    {
    {
      /* This is a default operand for a field.  How can we tell if the
      /* This is a default operand for a field.  How can we tell if the
         value fits in the field?  Write the value into the field,
         value fits in the field?  Write the value into the field,
         read it back, and then make sure we get the same value.  */
         read it back, and then make sure we get the same value.  */
 
 
      xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
      xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
      static xtensa_insnbuf tmpbuf = 0;
      static xtensa_insnbuf tmpbuf = 0;
      int slot_id;
      int slot_id;
 
 
      if (!tmpbuf)
      if (!tmpbuf)
        {
        {
          tmpbuf = xtensa_insnbuf_alloc (isa);
          tmpbuf = xtensa_insnbuf_alloc (isa);
          CHECK_ALLOC (tmpbuf, -1);
          CHECK_ALLOC (tmpbuf, -1);
        }
        }
 
 
      /* A default operand is always associated with a field,
      /* A default operand is always associated with a field,
         but check just to be sure....  */
         but check just to be sure....  */
      if (intop->field_id == XTENSA_UNDEFINED)
      if (intop->field_id == XTENSA_UNDEFINED)
        {
        {
          xtisa_errno = xtensa_isa_internal_error;
          xtisa_errno = xtensa_isa_internal_error;
          strcpy (xtisa_error_msg, "operand has no field");
          strcpy (xtisa_error_msg, "operand has no field");
          return -1;
          return -1;
        }
        }
 
 
      /* Find some slot that includes the field.  */
      /* Find some slot that includes the field.  */
      for (slot_id = 0; slot_id < intisa->num_slots; slot_id++)
      for (slot_id = 0; slot_id < intisa->num_slots; slot_id++)
        {
        {
          xtensa_get_field_fn get_fn =
          xtensa_get_field_fn get_fn =
            intisa->slots[slot_id].get_field_fns[intop->field_id];
            intisa->slots[slot_id].get_field_fns[intop->field_id];
          xtensa_set_field_fn set_fn =
          xtensa_set_field_fn set_fn =
            intisa->slots[slot_id].set_field_fns[intop->field_id];
            intisa->slots[slot_id].set_field_fns[intop->field_id];
 
 
          if (get_fn && set_fn)
          if (get_fn && set_fn)
            {
            {
              (*set_fn) (tmpbuf, *valp);
              (*set_fn) (tmpbuf, *valp);
              return ((*get_fn) (tmpbuf) != *valp);
              return ((*get_fn) (tmpbuf) != *valp);
            }
            }
        }
        }
 
 
      /* Couldn't find any slot containing the field....  */
      /* Couldn't find any slot containing the field....  */
      xtisa_errno = xtensa_isa_no_field;
      xtisa_errno = xtensa_isa_no_field;
      strcpy (xtisa_error_msg, "field does not exist in any slot");
      strcpy (xtisa_error_msg, "field does not exist in any slot");
      return -1;
      return -1;
    }
    }
 
 
  /* Encode the value.  In some cases, the encoding function may detect
  /* Encode the value.  In some cases, the encoding function may detect
     errors, but most of the time the only way to determine if the value
     errors, but most of the time the only way to determine if the value
     was successfully encoded is to decode it and check if it matches
     was successfully encoded is to decode it and check if it matches
     the original value.  */
     the original value.  */
  orig_val = *valp;
  orig_val = *valp;
  if ((*intop->encode) (valp) ||
  if ((*intop->encode) (valp) ||
      (test_val = *valp, (*intop->decode) (&test_val)) ||
      (test_val = *valp, (*intop->decode) (&test_val)) ||
      test_val != orig_val)
      test_val != orig_val)
    {
    {
      xtisa_errno = xtensa_isa_bad_value;
      xtisa_errno = xtensa_isa_bad_value;
      sprintf (xtisa_error_msg, "cannot encode operand value 0x%08x", *valp);
      sprintf (xtisa_error_msg, "cannot encode operand value 0x%08x", *valp);
      return -1;
      return -1;
    }
    }
 
 
  return 0;
  return 0;
}
}
 
 
 
 
int
int
xtensa_operand_decode (xtensa_isa isa, xtensa_opcode opc, int opnd,
xtensa_operand_decode (xtensa_isa isa, xtensa_opcode opc, int opnd,
                       uint32 *valp)
                       uint32 *valp)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_operand_internal *intop;
  xtensa_operand_internal *intop;
 
 
  intop = get_operand (intisa, opc, opnd);
  intop = get_operand (intisa, opc, opnd);
  if (!intop) return -1;
  if (!intop) return -1;
 
 
  /* Use identity function for "default" operands.  */
  /* Use identity function for "default" operands.  */
  if (!intop->decode)
  if (!intop->decode)
    return 0;
    return 0;
 
 
  if ((*intop->decode) (valp))
  if ((*intop->decode) (valp))
    {
    {
      xtisa_errno = xtensa_isa_bad_value;
      xtisa_errno = xtensa_isa_bad_value;
      sprintf (xtisa_error_msg, "cannot decode operand value 0x%08x", *valp);
      sprintf (xtisa_error_msg, "cannot decode operand value 0x%08x", *valp);
      return -1;
      return -1;
    }
    }
  return 0;
  return 0;
}
}
 
 
 
 
int
int
xtensa_operand_is_register (xtensa_isa isa, xtensa_opcode opc, int opnd)
xtensa_operand_is_register (xtensa_isa isa, xtensa_opcode opc, int opnd)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_operand_internal *intop;
  xtensa_operand_internal *intop;
 
 
  intop = get_operand (intisa, opc, opnd);
  intop = get_operand (intisa, opc, opnd);
  if (!intop) return XTENSA_UNDEFINED;
  if (!intop) return XTENSA_UNDEFINED;
 
 
  if ((intop->flags & XTENSA_OPERAND_IS_REGISTER) != 0)
  if ((intop->flags & XTENSA_OPERAND_IS_REGISTER) != 0)
    return 1;
    return 1;
  return 0;
  return 0;
}
}
 
 
 
 
xtensa_regfile
xtensa_regfile
xtensa_operand_regfile (xtensa_isa isa, xtensa_opcode opc, int opnd)
xtensa_operand_regfile (xtensa_isa isa, xtensa_opcode opc, int opnd)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_operand_internal *intop;
  xtensa_operand_internal *intop;
 
 
  intop = get_operand (intisa, opc, opnd);
  intop = get_operand (intisa, opc, opnd);
  if (!intop) return XTENSA_UNDEFINED;
  if (!intop) return XTENSA_UNDEFINED;
 
 
  return intop->regfile;
  return intop->regfile;
}
}
 
 
 
 
int
int
xtensa_operand_num_regs (xtensa_isa isa, xtensa_opcode opc, int opnd)
xtensa_operand_num_regs (xtensa_isa isa, xtensa_opcode opc, int opnd)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_operand_internal *intop;
  xtensa_operand_internal *intop;
 
 
  intop = get_operand (intisa, opc, opnd);
  intop = get_operand (intisa, opc, opnd);
  if (!intop) return XTENSA_UNDEFINED;
  if (!intop) return XTENSA_UNDEFINED;
 
 
  return intop->num_regs;
  return intop->num_regs;
}
}
 
 
 
 
int
int
xtensa_operand_is_known_reg (xtensa_isa isa, xtensa_opcode opc, int opnd)
xtensa_operand_is_known_reg (xtensa_isa isa, xtensa_opcode opc, int opnd)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_operand_internal *intop;
  xtensa_operand_internal *intop;
 
 
  intop = get_operand (intisa, opc, opnd);
  intop = get_operand (intisa, opc, opnd);
  if (!intop) return XTENSA_UNDEFINED;
  if (!intop) return XTENSA_UNDEFINED;
 
 
  if ((intop->flags & XTENSA_OPERAND_IS_UNKNOWN) == 0)
  if ((intop->flags & XTENSA_OPERAND_IS_UNKNOWN) == 0)
    return 1;
    return 1;
  return 0;
  return 0;
}
}
 
 
 
 
int
int
xtensa_operand_is_PCrelative (xtensa_isa isa, xtensa_opcode opc, int opnd)
xtensa_operand_is_PCrelative (xtensa_isa isa, xtensa_opcode opc, int opnd)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_operand_internal *intop;
  xtensa_operand_internal *intop;
 
 
  intop = get_operand (intisa, opc, opnd);
  intop = get_operand (intisa, opc, opnd);
  if (!intop) return XTENSA_UNDEFINED;
  if (!intop) return XTENSA_UNDEFINED;
 
 
  if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) != 0)
  if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) != 0)
    return 1;
    return 1;
  return 0;
  return 0;
}
}
 
 
 
 
int
int
xtensa_operand_do_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
xtensa_operand_do_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
                         uint32 *valp, uint32 pc)
                         uint32 *valp, uint32 pc)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_operand_internal *intop;
  xtensa_operand_internal *intop;
 
 
  intop = get_operand (intisa, opc, opnd);
  intop = get_operand (intisa, opc, opnd);
  if (!intop) return -1;
  if (!intop) return -1;
 
 
  if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0)
  if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0)
    return 0;
    return 0;
 
 
  if (!intop->do_reloc)
  if (!intop->do_reloc)
    {
    {
      xtisa_errno = xtensa_isa_internal_error;
      xtisa_errno = xtensa_isa_internal_error;
      strcpy (xtisa_error_msg, "operand missing do_reloc function");
      strcpy (xtisa_error_msg, "operand missing do_reloc function");
      return -1;
      return -1;
    }
    }
 
 
  if ((*intop->do_reloc) (valp, pc))
  if ((*intop->do_reloc) (valp, pc))
    {
    {
      xtisa_errno = xtensa_isa_bad_value;
      xtisa_errno = xtensa_isa_bad_value;
      sprintf (xtisa_error_msg,
      sprintf (xtisa_error_msg,
               "do_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc);
               "do_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc);
      return -1;
      return -1;
    }
    }
 
 
  return 0;
  return 0;
}
}
 
 
 
 
int
int
xtensa_operand_undo_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
xtensa_operand_undo_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
                           uint32 *valp, uint32 pc)
                           uint32 *valp, uint32 pc)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_operand_internal *intop;
  xtensa_operand_internal *intop;
 
 
  intop = get_operand (intisa, opc, opnd);
  intop = get_operand (intisa, opc, opnd);
  if (!intop) return -1;
  if (!intop) return -1;
 
 
  if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0)
  if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0)
    return 0;
    return 0;
 
 
  if (!intop->undo_reloc)
  if (!intop->undo_reloc)
    {
    {
      xtisa_errno = xtensa_isa_internal_error;
      xtisa_errno = xtensa_isa_internal_error;
      strcpy (xtisa_error_msg, "operand missing undo_reloc function");
      strcpy (xtisa_error_msg, "operand missing undo_reloc function");
      return -1;
      return -1;
    }
    }
 
 
  if ((*intop->undo_reloc) (valp, pc))
  if ((*intop->undo_reloc) (valp, pc))
    {
    {
      xtisa_errno = xtensa_isa_bad_value;
      xtisa_errno = xtensa_isa_bad_value;
      sprintf (xtisa_error_msg,
      sprintf (xtisa_error_msg,
               "undo_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc);
               "undo_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc);
      return -1;
      return -1;
    }
    }
 
 
  return 0;
  return 0;
}
}
 
 
 
 


/* State Operands.  */
/* State Operands.  */
 
 
 
 
#define CHECK_STATE_OPERAND(INTISA,OPC,ICLASS,STOP,ERRVAL) \
#define CHECK_STATE_OPERAND(INTISA,OPC,ICLASS,STOP,ERRVAL) \
  do { \
  do { \
    if ((STOP) < 0 || (STOP) >= (ICLASS)->num_stateOperands) \
    if ((STOP) < 0 || (STOP) >= (ICLASS)->num_stateOperands) \
      { \
      { \
        xtisa_errno = xtensa_isa_bad_operand; \
        xtisa_errno = xtensa_isa_bad_operand; \
        sprintf (xtisa_error_msg, "invalid state operand number (%d); " \
        sprintf (xtisa_error_msg, "invalid state operand number (%d); " \
                 "opcode \"%s\" has %d state operands", (STOP), \
                 "opcode \"%s\" has %d state operands", (STOP), \
                 (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_stateOperands); \
                 (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_stateOperands); \
        return (ERRVAL); \
        return (ERRVAL); \
      } \
      } \
  } while (0)
  } while (0)
 
 
 
 
xtensa_state
xtensa_state
xtensa_stateOperand_state (xtensa_isa isa, xtensa_opcode opc, int stOp)
xtensa_stateOperand_state (xtensa_isa isa, xtensa_opcode opc, int stOp)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_iclass_internal *iclass;
  xtensa_iclass_internal *iclass;
  int iclass_id;
  int iclass_id;
 
 
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  iclass_id = intisa->opcodes[opc].iclass_id;
  iclass_id = intisa->opcodes[opc].iclass_id;
  iclass = &intisa->iclasses[iclass_id];
  iclass = &intisa->iclasses[iclass_id];
  CHECK_STATE_OPERAND (intisa, opc, iclass, stOp, XTENSA_UNDEFINED);
  CHECK_STATE_OPERAND (intisa, opc, iclass, stOp, XTENSA_UNDEFINED);
  return iclass->stateOperands[stOp].u.state;
  return iclass->stateOperands[stOp].u.state;
}
}
 
 
 
 
char
char
xtensa_stateOperand_inout (xtensa_isa isa, xtensa_opcode opc, int stOp)
xtensa_stateOperand_inout (xtensa_isa isa, xtensa_opcode opc, int stOp)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_iclass_internal *iclass;
  xtensa_iclass_internal *iclass;
  int iclass_id;
  int iclass_id;
 
 
  CHECK_OPCODE (intisa, opc, 0);
  CHECK_OPCODE (intisa, opc, 0);
  iclass_id = intisa->opcodes[opc].iclass_id;
  iclass_id = intisa->opcodes[opc].iclass_id;
  iclass = &intisa->iclasses[iclass_id];
  iclass = &intisa->iclasses[iclass_id];
  CHECK_STATE_OPERAND (intisa, opc, iclass, stOp, 0);
  CHECK_STATE_OPERAND (intisa, opc, iclass, stOp, 0);
  return iclass->stateOperands[stOp].inout;
  return iclass->stateOperands[stOp].inout;
}
}
 
 
 
 


/* Interface Operands.  */
/* Interface Operands.  */
 
 
 
 
#define CHECK_INTERFACE_OPERAND(INTISA,OPC,ICLASS,IFOP,ERRVAL) \
#define CHECK_INTERFACE_OPERAND(INTISA,OPC,ICLASS,IFOP,ERRVAL) \
  do { \
  do { \
    if ((IFOP) < 0 || (IFOP) >= (ICLASS)->num_interfaceOperands) \
    if ((IFOP) < 0 || (IFOP) >= (ICLASS)->num_interfaceOperands) \
      { \
      { \
        xtisa_errno = xtensa_isa_bad_operand; \
        xtisa_errno = xtensa_isa_bad_operand; \
        sprintf (xtisa_error_msg, "invalid interface operand number (%d); " \
        sprintf (xtisa_error_msg, "invalid interface operand number (%d); " \
                 "opcode \"%s\" has %d interface operands", (IFOP), \
                 "opcode \"%s\" has %d interface operands", (IFOP), \
                 (INTISA)->opcodes[(OPC)].name, \
                 (INTISA)->opcodes[(OPC)].name, \
                 (ICLASS)->num_interfaceOperands); \
                 (ICLASS)->num_interfaceOperands); \
        return (ERRVAL); \
        return (ERRVAL); \
      } \
      } \
  } while (0)
  } while (0)
 
 
 
 
xtensa_interface
xtensa_interface
xtensa_interfaceOperand_interface (xtensa_isa isa, xtensa_opcode opc,
xtensa_interfaceOperand_interface (xtensa_isa isa, xtensa_opcode opc,
                                   int ifOp)
                                   int ifOp)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_iclass_internal *iclass;
  xtensa_iclass_internal *iclass;
  int iclass_id;
  int iclass_id;
 
 
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
  iclass_id = intisa->opcodes[opc].iclass_id;
  iclass_id = intisa->opcodes[opc].iclass_id;
  iclass = &intisa->iclasses[iclass_id];
  iclass = &intisa->iclasses[iclass_id];
  CHECK_INTERFACE_OPERAND (intisa, opc, iclass, ifOp, XTENSA_UNDEFINED);
  CHECK_INTERFACE_OPERAND (intisa, opc, iclass, ifOp, XTENSA_UNDEFINED);
  return iclass->interfaceOperands[ifOp];
  return iclass->interfaceOperands[ifOp];
}
}
 
 
 
 


/* Register Files.  */
/* Register Files.  */
 
 
 
 
#define CHECK_REGFILE(INTISA,RF,ERRVAL) \
#define CHECK_REGFILE(INTISA,RF,ERRVAL) \
  do { \
  do { \
    if ((RF) < 0 || (RF) >= (INTISA)->num_regfiles) \
    if ((RF) < 0 || (RF) >= (INTISA)->num_regfiles) \
      { \
      { \
        xtisa_errno = xtensa_isa_bad_regfile; \
        xtisa_errno = xtensa_isa_bad_regfile; \
        strcpy (xtisa_error_msg, "invalid regfile specifier"); \
        strcpy (xtisa_error_msg, "invalid regfile specifier"); \
        return (ERRVAL); \
        return (ERRVAL); \
      } \
      } \
  } while (0)
  } while (0)
 
 
 
 
xtensa_regfile
xtensa_regfile
xtensa_regfile_lookup (xtensa_isa isa, const char *name)
xtensa_regfile_lookup (xtensa_isa isa, const char *name)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  int n;
  int n;
 
 
  if (!name || !*name)
  if (!name || !*name)
    {
    {
      xtisa_errno = xtensa_isa_bad_regfile;
      xtisa_errno = xtensa_isa_bad_regfile;
      strcpy (xtisa_error_msg, "invalid regfile name");
      strcpy (xtisa_error_msg, "invalid regfile name");
      return XTENSA_UNDEFINED;
      return XTENSA_UNDEFINED;
    }
    }
 
 
  /* The expected number of regfiles is small; use a linear search.  */
  /* The expected number of regfiles is small; use a linear search.  */
  for (n = 0; n < intisa->num_regfiles; n++)
  for (n = 0; n < intisa->num_regfiles; n++)
    {
    {
      if (!strcmp (intisa->regfiles[n].name, name))
      if (!strcmp (intisa->regfiles[n].name, name))
        return n;
        return n;
    }
    }
 
 
  xtisa_errno = xtensa_isa_bad_regfile;
  xtisa_errno = xtensa_isa_bad_regfile;
  sprintf (xtisa_error_msg, "regfile \"%s\" not recognized", name);
  sprintf (xtisa_error_msg, "regfile \"%s\" not recognized", name);
  return XTENSA_UNDEFINED;
  return XTENSA_UNDEFINED;
}
}
 
 
 
 
xtensa_regfile
xtensa_regfile
xtensa_regfile_lookup_shortname (xtensa_isa isa, const char *shortname)
xtensa_regfile_lookup_shortname (xtensa_isa isa, const char *shortname)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  int n;
  int n;
 
 
  if (!shortname || !*shortname)
  if (!shortname || !*shortname)
    {
    {
      xtisa_errno = xtensa_isa_bad_regfile;
      xtisa_errno = xtensa_isa_bad_regfile;
      strcpy (xtisa_error_msg, "invalid regfile shortname");
      strcpy (xtisa_error_msg, "invalid regfile shortname");
      return XTENSA_UNDEFINED;
      return XTENSA_UNDEFINED;
    }
    }
 
 
  /* The expected number of regfiles is small; use a linear search.  */
  /* The expected number of regfiles is small; use a linear search.  */
  for (n = 0; n < intisa->num_regfiles; n++)
  for (n = 0; n < intisa->num_regfiles; n++)
    {
    {
      /* Ignore regfile views since they always have the same shortnames
      /* Ignore regfile views since they always have the same shortnames
         as their parents.  */
         as their parents.  */
      if (intisa->regfiles[n].parent != n)
      if (intisa->regfiles[n].parent != n)
        continue;
        continue;
      if (!strcmp (intisa->regfiles[n].shortname, shortname))
      if (!strcmp (intisa->regfiles[n].shortname, shortname))
        return n;
        return n;
    }
    }
 
 
  xtisa_errno = xtensa_isa_bad_regfile;
  xtisa_errno = xtensa_isa_bad_regfile;
  sprintf (xtisa_error_msg, "regfile shortname \"%s\" not recognized",
  sprintf (xtisa_error_msg, "regfile shortname \"%s\" not recognized",
           shortname);
           shortname);
  return XTENSA_UNDEFINED;
  return XTENSA_UNDEFINED;
}
}
 
 
 
 
const char *
const char *
xtensa_regfile_name (xtensa_isa isa, xtensa_regfile rf)
xtensa_regfile_name (xtensa_isa isa, xtensa_regfile rf)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_REGFILE (intisa, rf, NULL);
  CHECK_REGFILE (intisa, rf, NULL);
  return intisa->regfiles[rf].name;
  return intisa->regfiles[rf].name;
}
}
 
 
 
 
const char *
const char *
xtensa_regfile_shortname (xtensa_isa isa, xtensa_regfile rf)
xtensa_regfile_shortname (xtensa_isa isa, xtensa_regfile rf)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_REGFILE (intisa, rf, NULL);
  CHECK_REGFILE (intisa, rf, NULL);
  return intisa->regfiles[rf].shortname;
  return intisa->regfiles[rf].shortname;
}
}
 
 
 
 
xtensa_regfile
xtensa_regfile
xtensa_regfile_view_parent (xtensa_isa isa, xtensa_regfile rf)
xtensa_regfile_view_parent (xtensa_isa isa, xtensa_regfile rf)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
  CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
  return intisa->regfiles[rf].parent;
  return intisa->regfiles[rf].parent;
}
}
 
 
 
 
int
int
xtensa_regfile_num_bits (xtensa_isa isa, xtensa_regfile rf)
xtensa_regfile_num_bits (xtensa_isa isa, xtensa_regfile rf)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
  CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
  return intisa->regfiles[rf].num_bits;
  return intisa->regfiles[rf].num_bits;
}
}
 
 
 
 
int
int
xtensa_regfile_num_entries (xtensa_isa isa, xtensa_regfile rf)
xtensa_regfile_num_entries (xtensa_isa isa, xtensa_regfile rf)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
  CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
  return intisa->regfiles[rf].num_entries;
  return intisa->regfiles[rf].num_entries;
}
}
 
 
 
 


/* Processor States.  */
/* Processor States.  */
 
 
 
 
#define CHECK_STATE(INTISA,ST,ERRVAL) \
#define CHECK_STATE(INTISA,ST,ERRVAL) \
  do { \
  do { \
    if ((ST) < 0 || (ST) >= (INTISA)->num_states) \
    if ((ST) < 0 || (ST) >= (INTISA)->num_states) \
      { \
      { \
        xtisa_errno = xtensa_isa_bad_state; \
        xtisa_errno = xtensa_isa_bad_state; \
        strcpy (xtisa_error_msg, "invalid state specifier"); \
        strcpy (xtisa_error_msg, "invalid state specifier"); \
        return (ERRVAL); \
        return (ERRVAL); \
      } \
      } \
  } while (0)
  } while (0)
 
 
 
 
xtensa_state
xtensa_state
xtensa_state_lookup (xtensa_isa isa, const char *name)
xtensa_state_lookup (xtensa_isa isa, const char *name)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_lookup_entry entry, *result = 0;
  xtensa_lookup_entry entry, *result = 0;
 
 
  if (!name || !*name)
  if (!name || !*name)
    {
    {
      xtisa_errno = xtensa_isa_bad_state;
      xtisa_errno = xtensa_isa_bad_state;
      strcpy (xtisa_error_msg, "invalid state name");
      strcpy (xtisa_error_msg, "invalid state name");
      return XTENSA_UNDEFINED;
      return XTENSA_UNDEFINED;
    }
    }
 
 
  if (intisa->num_states != 0)
  if (intisa->num_states != 0)
    {
    {
      entry.key = name;
      entry.key = name;
      result = bsearch (&entry, intisa->state_lookup_table, intisa->num_states,
      result = bsearch (&entry, intisa->state_lookup_table, intisa->num_states,
                        sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
                        sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
    }
    }
 
 
  if (!result)
  if (!result)
    {
    {
      xtisa_errno = xtensa_isa_bad_state;
      xtisa_errno = xtensa_isa_bad_state;
      sprintf (xtisa_error_msg, "state \"%s\" not recognized", name);
      sprintf (xtisa_error_msg, "state \"%s\" not recognized", name);
      return XTENSA_UNDEFINED;
      return XTENSA_UNDEFINED;
    }
    }
 
 
  return result->u.state;
  return result->u.state;
}
}
 
 
 
 
const char *
const char *
xtensa_state_name (xtensa_isa isa, xtensa_state st)
xtensa_state_name (xtensa_isa isa, xtensa_state st)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_STATE (intisa, st, NULL);
  CHECK_STATE (intisa, st, NULL);
  return intisa->states[st].name;
  return intisa->states[st].name;
}
}
 
 
 
 
int
int
xtensa_state_num_bits (xtensa_isa isa, xtensa_state st)
xtensa_state_num_bits (xtensa_isa isa, xtensa_state st)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
  CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
  return intisa->states[st].num_bits;
  return intisa->states[st].num_bits;
}
}
 
 
 
 
int
int
xtensa_state_is_exported (xtensa_isa isa, xtensa_state st)
xtensa_state_is_exported (xtensa_isa isa, xtensa_state st)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
  CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
  if ((intisa->states[st].flags & XTENSA_STATE_IS_EXPORTED) != 0)
  if ((intisa->states[st].flags & XTENSA_STATE_IS_EXPORTED) != 0)
    return 1;
    return 1;
  return 0;
  return 0;
}
}
 
 
 
 
int
int
xtensa_state_is_shared_or (xtensa_isa isa, xtensa_state st)
xtensa_state_is_shared_or (xtensa_isa isa, xtensa_state st)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
  CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
  if ((intisa->states[st].flags & XTENSA_STATE_IS_SHARED_OR) != 0)
  if ((intisa->states[st].flags & XTENSA_STATE_IS_SHARED_OR) != 0)
    return 1;
    return 1;
  return 0;
  return 0;
}
}
 
 
 
 


/* Sysregs.  */
/* Sysregs.  */
 
 
 
 
#define CHECK_SYSREG(INTISA,SYSREG,ERRVAL) \
#define CHECK_SYSREG(INTISA,SYSREG,ERRVAL) \
  do { \
  do { \
    if ((SYSREG) < 0 || (SYSREG) >= (INTISA)->num_sysregs) \
    if ((SYSREG) < 0 || (SYSREG) >= (INTISA)->num_sysregs) \
      { \
      { \
        xtisa_errno = xtensa_isa_bad_sysreg; \
        xtisa_errno = xtensa_isa_bad_sysreg; \
        strcpy (xtisa_error_msg, "invalid sysreg specifier"); \
        strcpy (xtisa_error_msg, "invalid sysreg specifier"); \
        return (ERRVAL); \
        return (ERRVAL); \
      } \
      } \
  } while (0)
  } while (0)
 
 
 
 
xtensa_sysreg
xtensa_sysreg
xtensa_sysreg_lookup (xtensa_isa isa, int num, int is_user)
xtensa_sysreg_lookup (xtensa_isa isa, int num, int is_user)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
 
 
  if (is_user != 0)
  if (is_user != 0)
    is_user = 1;
    is_user = 1;
 
 
  if (num < 0 || num > intisa->max_sysreg_num[is_user]
  if (num < 0 || num > intisa->max_sysreg_num[is_user]
      || intisa->sysreg_table[is_user][num] == XTENSA_UNDEFINED)
      || intisa->sysreg_table[is_user][num] == XTENSA_UNDEFINED)
    {
    {
      xtisa_errno = xtensa_isa_bad_sysreg;
      xtisa_errno = xtensa_isa_bad_sysreg;
      strcpy (xtisa_error_msg, "sysreg not recognized");
      strcpy (xtisa_error_msg, "sysreg not recognized");
      return XTENSA_UNDEFINED;
      return XTENSA_UNDEFINED;
    }
    }
 
 
  return intisa->sysreg_table[is_user][num];
  return intisa->sysreg_table[is_user][num];
}
}
 
 
 
 
xtensa_sysreg
xtensa_sysreg
xtensa_sysreg_lookup_name (xtensa_isa isa, const char *name)
xtensa_sysreg_lookup_name (xtensa_isa isa, const char *name)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_lookup_entry entry, *result = 0;
  xtensa_lookup_entry entry, *result = 0;
 
 
  if (!name || !*name)
  if (!name || !*name)
    {
    {
      xtisa_errno = xtensa_isa_bad_sysreg;
      xtisa_errno = xtensa_isa_bad_sysreg;
      strcpy (xtisa_error_msg, "invalid sysreg name");
      strcpy (xtisa_error_msg, "invalid sysreg name");
      return XTENSA_UNDEFINED;
      return XTENSA_UNDEFINED;
    }
    }
 
 
  if (intisa->num_sysregs != 0)
  if (intisa->num_sysregs != 0)
    {
    {
      entry.key = name;
      entry.key = name;
      result = bsearch (&entry, intisa->sysreg_lookup_table,
      result = bsearch (&entry, intisa->sysreg_lookup_table,
                        intisa->num_sysregs, sizeof (xtensa_lookup_entry),
                        intisa->num_sysregs, sizeof (xtensa_lookup_entry),
                        xtensa_isa_name_compare);
                        xtensa_isa_name_compare);
    }
    }
 
 
  if (!result)
  if (!result)
    {
    {
      xtisa_errno = xtensa_isa_bad_sysreg;
      xtisa_errno = xtensa_isa_bad_sysreg;
      sprintf (xtisa_error_msg, "sysreg \"%s\" not recognized", name);
      sprintf (xtisa_error_msg, "sysreg \"%s\" not recognized", name);
      return XTENSA_UNDEFINED;
      return XTENSA_UNDEFINED;
    }
    }
 
 
  return result->u.sysreg;
  return result->u.sysreg;
}
}
 
 
 
 
const char *
const char *
xtensa_sysreg_name (xtensa_isa isa, xtensa_sysreg sysreg)
xtensa_sysreg_name (xtensa_isa isa, xtensa_sysreg sysreg)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_SYSREG (intisa, sysreg, NULL);
  CHECK_SYSREG (intisa, sysreg, NULL);
  return intisa->sysregs[sysreg].name;
  return intisa->sysregs[sysreg].name;
}
}
 
 
 
 
int
int
xtensa_sysreg_number (xtensa_isa isa, xtensa_sysreg sysreg)
xtensa_sysreg_number (xtensa_isa isa, xtensa_sysreg sysreg)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED);
  CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED);
  return intisa->sysregs[sysreg].number;
  return intisa->sysregs[sysreg].number;
}
}
 
 
 
 
int
int
xtensa_sysreg_is_user (xtensa_isa isa, xtensa_sysreg sysreg)
xtensa_sysreg_is_user (xtensa_isa isa, xtensa_sysreg sysreg)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED);
  CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED);
  if (intisa->sysregs[sysreg].is_user)
  if (intisa->sysregs[sysreg].is_user)
    return 1;
    return 1;
  return 0;
  return 0;
}
}
 
 
 
 


/* Interfaces.  */
/* Interfaces.  */
 
 
 
 
#define CHECK_INTERFACE(INTISA,INTF,ERRVAL) \
#define CHECK_INTERFACE(INTISA,INTF,ERRVAL) \
  do { \
  do { \
    if ((INTF) < 0 || (INTF) >= (INTISA)->num_interfaces) \
    if ((INTF) < 0 || (INTF) >= (INTISA)->num_interfaces) \
      { \
      { \
        xtisa_errno = xtensa_isa_bad_interface; \
        xtisa_errno = xtensa_isa_bad_interface; \
        strcpy (xtisa_error_msg, "invalid interface specifier"); \
        strcpy (xtisa_error_msg, "invalid interface specifier"); \
        return (ERRVAL); \
        return (ERRVAL); \
      } \
      } \
  } while (0)
  } while (0)
 
 
 
 
xtensa_interface
xtensa_interface
xtensa_interface_lookup (xtensa_isa isa, const char *ifname)
xtensa_interface_lookup (xtensa_isa isa, const char *ifname)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_lookup_entry entry, *result = 0;
  xtensa_lookup_entry entry, *result = 0;
 
 
  if (!ifname || !*ifname)
  if (!ifname || !*ifname)
    {
    {
      xtisa_errno = xtensa_isa_bad_interface;
      xtisa_errno = xtensa_isa_bad_interface;
      strcpy (xtisa_error_msg, "invalid interface name");
      strcpy (xtisa_error_msg, "invalid interface name");
      return XTENSA_UNDEFINED;
      return XTENSA_UNDEFINED;
    }
    }
 
 
  if (intisa->num_interfaces != 0)
  if (intisa->num_interfaces != 0)
    {
    {
      entry.key = ifname;
      entry.key = ifname;
      result = bsearch (&entry, intisa->interface_lookup_table,
      result = bsearch (&entry, intisa->interface_lookup_table,
                        intisa->num_interfaces, sizeof (xtensa_lookup_entry),
                        intisa->num_interfaces, sizeof (xtensa_lookup_entry),
                        xtensa_isa_name_compare);
                        xtensa_isa_name_compare);
    }
    }
 
 
  if (!result)
  if (!result)
    {
    {
      xtisa_errno = xtensa_isa_bad_interface;
      xtisa_errno = xtensa_isa_bad_interface;
      sprintf (xtisa_error_msg, "interface \"%s\" not recognized", ifname);
      sprintf (xtisa_error_msg, "interface \"%s\" not recognized", ifname);
      return XTENSA_UNDEFINED;
      return XTENSA_UNDEFINED;
    }
    }
 
 
  return result->u.intf;
  return result->u.intf;
}
}
 
 
 
 
const char *
const char *
xtensa_interface_name (xtensa_isa isa, xtensa_interface intf)
xtensa_interface_name (xtensa_isa isa, xtensa_interface intf)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_INTERFACE (intisa, intf, NULL);
  CHECK_INTERFACE (intisa, intf, NULL);
  return intisa->interfaces[intf].name;
  return intisa->interfaces[intf].name;
}
}
 
 
 
 
int
int
xtensa_interface_num_bits (xtensa_isa isa, xtensa_interface intf)
xtensa_interface_num_bits (xtensa_isa isa, xtensa_interface intf)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
  CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
  return intisa->interfaces[intf].num_bits;
  return intisa->interfaces[intf].num_bits;
}
}
 
 
 
 
char
char
xtensa_interface_inout (xtensa_isa isa, xtensa_interface intf)
xtensa_interface_inout (xtensa_isa isa, xtensa_interface intf)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_INTERFACE (intisa, intf, 0);
  CHECK_INTERFACE (intisa, intf, 0);
  return intisa->interfaces[intf].inout;
  return intisa->interfaces[intf].inout;
}
}
 
 
 
 
int
int
xtensa_interface_has_side_effect (xtensa_isa isa, xtensa_interface intf)
xtensa_interface_has_side_effect (xtensa_isa isa, xtensa_interface intf)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
  CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
  if ((intisa->interfaces[intf].flags & XTENSA_INTERFACE_HAS_SIDE_EFFECT) != 0)
  if ((intisa->interfaces[intf].flags & XTENSA_INTERFACE_HAS_SIDE_EFFECT) != 0)
    return 1;
    return 1;
  return 0;
  return 0;
}
}
 
 
 
 
int
int
xtensa_interface_class_id (xtensa_isa isa, xtensa_interface intf)
xtensa_interface_class_id (xtensa_isa isa, xtensa_interface intf)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
  CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED);
  return intisa->interfaces[intf].class_id;
  return intisa->interfaces[intf].class_id;
}
}
 
 
 
 


/* Functional Units.  */
/* Functional Units.  */
 
 
 
 
#define CHECK_FUNCUNIT(INTISA,FUN,ERRVAL) \
#define CHECK_FUNCUNIT(INTISA,FUN,ERRVAL) \
  do { \
  do { \
    if ((FUN) < 0 || (FUN) >= (INTISA)->num_funcUnits) \
    if ((FUN) < 0 || (FUN) >= (INTISA)->num_funcUnits) \
      { \
      { \
        xtisa_errno = xtensa_isa_bad_funcUnit; \
        xtisa_errno = xtensa_isa_bad_funcUnit; \
        strcpy (xtisa_error_msg, "invalid functional unit specifier"); \
        strcpy (xtisa_error_msg, "invalid functional unit specifier"); \
        return (ERRVAL); \
        return (ERRVAL); \
      } \
      } \
  } while (0)
  } while (0)
 
 
 
 
xtensa_funcUnit
xtensa_funcUnit
xtensa_funcUnit_lookup (xtensa_isa isa, const char *fname)
xtensa_funcUnit_lookup (xtensa_isa isa, const char *fname)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_lookup_entry entry, *result = 0;
  xtensa_lookup_entry entry, *result = 0;
 
 
  if (!fname || !*fname)
  if (!fname || !*fname)
    {
    {
      xtisa_errno = xtensa_isa_bad_funcUnit;
      xtisa_errno = xtensa_isa_bad_funcUnit;
      strcpy (xtisa_error_msg, "invalid functional unit name");
      strcpy (xtisa_error_msg, "invalid functional unit name");
      return XTENSA_UNDEFINED;
      return XTENSA_UNDEFINED;
    }
    }
 
 
  if (intisa->num_funcUnits != 0)
  if (intisa->num_funcUnits != 0)
    {
    {
      entry.key = fname;
      entry.key = fname;
      result = bsearch (&entry, intisa->funcUnit_lookup_table,
      result = bsearch (&entry, intisa->funcUnit_lookup_table,
                        intisa->num_funcUnits, sizeof (xtensa_lookup_entry),
                        intisa->num_funcUnits, sizeof (xtensa_lookup_entry),
                        xtensa_isa_name_compare);
                        xtensa_isa_name_compare);
    }
    }
 
 
  if (!result)
  if (!result)
    {
    {
      xtisa_errno = xtensa_isa_bad_funcUnit;
      xtisa_errno = xtensa_isa_bad_funcUnit;
      sprintf (xtisa_error_msg,
      sprintf (xtisa_error_msg,
               "functional unit \"%s\" not recognized", fname);
               "functional unit \"%s\" not recognized", fname);
      return XTENSA_UNDEFINED;
      return XTENSA_UNDEFINED;
    }
    }
 
 
  return result->u.fun;
  return result->u.fun;
}
}
 
 
 
 
const char *
const char *
xtensa_funcUnit_name (xtensa_isa isa, xtensa_funcUnit fun)
xtensa_funcUnit_name (xtensa_isa isa, xtensa_funcUnit fun)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_FUNCUNIT (intisa, fun, NULL);
  CHECK_FUNCUNIT (intisa, fun, NULL);
  return intisa->funcUnits[fun].name;
  return intisa->funcUnits[fun].name;
}
}
 
 
 
 
int
int
xtensa_funcUnit_num_copies (xtensa_isa isa, xtensa_funcUnit fun)
xtensa_funcUnit_num_copies (xtensa_isa isa, xtensa_funcUnit fun)
{
{
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
  CHECK_FUNCUNIT (intisa, fun, XTENSA_UNDEFINED);
  CHECK_FUNCUNIT (intisa, fun, XTENSA_UNDEFINED);
  return intisa->funcUnits[fun].num_copies;
  return intisa->funcUnits[fun].num_copies;
}
}
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.