/* Instruction printing code for the ARC.
   Copyright (C) 1994-2022 Free Software Foundation, Inc.

   Contributed by Claudiu Zissulescu (claziss@synopsys.com)

   This file is part of libopcodes.

   This library is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   It is distributed in the hope that it will be useful, but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
   License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "sysdep.h"
#include <stdio.h>
#include <assert.h>
#include "dis-asm.h"
#include "opcode/arc.h"
#include "elf/arc.h"
#include "arc-dis.h"
#include "arc-ext.h"
#include "elf-bfd.h"
#include "libiberty.h"
#include "opintl.h"

/* Structure used to iterate over, and extract the values for, operands of
   an opcode.  */

struct arc_operand_iterator
{
  /* The complete instruction value to extract operands from.  */
  unsigned long long insn;

  /* The LIMM if this is being tracked separately.  This field is only
     valid if we find the LIMM operand in the operand list.  */
  unsigned limm;

  /* The opcode this iterator is operating on.  */
  const struct arc_opcode *opcode;

  /* The index into the opcodes operand index list.  */
  const unsigned char *opidx;
};

/* A private data used by ARC decoder.  */
struct arc_disassemble_info
{
  /* The current disassembled arc opcode.  */
  const struct arc_opcode *opcode;

  /* Instruction length w/o limm field.  */
  unsigned insn_len;

  /* TRUE if we have limm.  */
  bool limm_p;

  /* LIMM value, if exists.  */
  unsigned limm;

  /* Condition code, if exists.  */
  unsigned condition_code;

  /* Writeback mode.  */
  unsigned writeback_mode;

  /* Number of operands.  */
  unsigned operands_count;

  struct arc_insn_operand operands[MAX_INSN_ARGS];
};

/* Globals variables.  */

static const char * const regnames[64] =
{
  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
  "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
  "r24", "r25", "gp", "fp", "sp", "ilink", "r30", "blink",

  "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
  "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
  "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",
  "r56", "r57", "r58", "r59", "lp_count", "reserved", "LIMM", "pcl"
};

static const char * const addrtypenames[ARC_NUM_ADDRTYPES] =
{
  "bd", "jid", "lbd", "mbd", "sd", "sm", "xa", "xd",
  "cd", "cbd", "cjid", "clbd", "cm", "csd", "cxa", "cxd"
};

static int addrtypenames_max = ARC_NUM_ADDRTYPES - 1;

static const char * const addrtypeunknown = "unknown";

/* This structure keeps track which instruction class(es)
   should be ignored durring disassembling.  */

typedef struct skipclass
{
  insn_class_t     insn_class;
  insn_subclass_t  subclass;
  struct skipclass *nxt;
} skipclass_t, *linkclass;

/* Intial classes of instructions to be consider first when
   disassembling.  */
static linkclass decodelist = NULL;

/* ISA mask value enforced via disassembler info options.  ARC_OPCODE_NONE
   value means that no CPU is enforced.  */

static unsigned enforced_isa_mask = ARC_OPCODE_NONE;

/* True if we want to print using only hex numbers.  */
static bool print_hex = false;

/* Macros section.  */

#ifdef DEBUG
# define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args)
#else
# define pr_debug(fmt, args...)
#endif

#define ARRANGE_ENDIAN(info, buf)					\
  (info->endian == BFD_ENDIAN_LITTLE ? bfd_getm32 (bfd_getl32 (buf))	\
   : bfd_getb32 (buf))

#define BITS(word,s,e)  (((word) >> (s)) & ((1ull << ((e) - (s)) << 1) - 1))
#define OPCODE_32BIT_INSN(word)	(BITS ((word), 27, 31))

/* Functions implementation.  */

/* Initialize private data.  */
static bool
init_arc_disasm_info (struct disassemble_info *info)
{
  struct arc_disassemble_info *arc_infop
    = calloc (sizeof (*arc_infop), 1);

  if (arc_infop == NULL)
    return false;

  info->private_data = arc_infop;
  return true;
}

/* Add a new element to the decode list.  */

static void
add_to_decodelist (insn_class_t     insn_class,
		   insn_subclass_t  subclass)
{
  linkclass t = (linkclass) xmalloc (sizeof (skipclass_t));

  t->insn_class = insn_class;
  t->subclass = subclass;
  t->nxt = decodelist;
  decodelist = t;
}

/* Return TRUE if we need to skip the opcode from being
   disassembled.  */

static bool
skip_this_opcode (const struct arc_opcode *opcode)
{
  linkclass t = decodelist;

  /* Check opcode for major 0x06, return if it is not in.  */
  if (arc_opcode_len (opcode) == 4
      && (OPCODE_32BIT_INSN (opcode->opcode) != 0x06
	  /* Can be an APEX extensions.  */
	  && OPCODE_32BIT_INSN (opcode->opcode) != 0x07))
    return false;

  /* or not a known truble class.  */
  switch (opcode->insn_class)
    {
    case FLOAT:
    case DSP:
    case ARITH:
    case MPY:
      break;
    default:
      return false;
    }

  while (t != NULL)
    {
      if ((t->insn_class == opcode->insn_class)
	  && (t->subclass == opcode->subclass))
	return false;
      t = t->nxt;
    }

  return true;
}

static bfd_vma
bfd_getm32 (unsigned int data)
{
  bfd_vma value = 0;

  value = ((data & 0xff00) | (data & 0xff)) << 16;
  value |= ((data & 0xff0000) | (data & 0xff000000)) >> 16;
  return value;
}

static bool
special_flag_p (const char *opname,
		const char *flgname)
{
  const struct arc_flag_special *flg_spec;
  unsigned i, j, flgidx;

  for (i = 0; i < arc_num_flag_special; i++)
    {
      flg_spec = &arc_flag_special_cases[i];

      if (strcmp (opname, flg_spec->name))
	continue;

      /* Found potential special case instruction.  */
      for (j=0;; ++j)
	{
	  flgidx = flg_spec->flags[j];
	  if (flgidx == 0)
	    break; /* End of the array.  */

	  if (strcmp (flgname, arc_flag_operands[flgidx].name) == 0)
	    return true;
	}
    }
  return false;
}

/* Find opcode from ARC_TABLE given the instruction described by INSN and
   INSNLEN.  The ISA_MASK restricts the possible matches in ARC_TABLE.  */

static const struct arc_opcode *
find_format_from_table (struct disassemble_info *info,
			const struct arc_opcode *arc_table,
                        unsigned long long insn,
			unsigned int insn_len,
                        unsigned isa_mask,
			bool *has_limm,
			bool overlaps)
{
  unsigned int i = 0;
  const struct arc_opcode *opcode = NULL;
  const struct arc_opcode *t_op = NULL;
  const unsigned char *opidx;
  const unsigned char *flgidx;
  bool warn_p = false;

  do
    {
      bool invalid = false;

      opcode = &arc_table[i++];

      if (!(opcode->cpu & isa_mask))
	continue;

      if (arc_opcode_len (opcode) != (int) insn_len)
	continue;

      if ((insn & opcode->mask) != opcode->opcode)
	continue;

      *has_limm = false;

      /* Possible candidate, check the operands.  */
      for (opidx = opcode->operands; *opidx; opidx++)
	{
	  int value, limmind;
	  const struct arc_operand *operand = &arc_operands[*opidx];

	  if (operand->flags & ARC_OPERAND_FAKE)
	    continue;

	  if (operand->extract)
	    value = (*operand->extract) (insn, &invalid);
	  else
	    value = (insn >> operand->shift) & ((1ull << operand->bits) - 1);

	  /* Check for LIMM indicator.  If it is there, then make sure
	     we pick the right format.  */
	  limmind = (isa_mask & ARC_OPCODE_ARCV2) ? 0x1E : 0x3E;
	  if (operand->flags & ARC_OPERAND_IR
	      && !(operand->flags & ARC_OPERAND_LIMM))
	    {
	      if ((value == 0x3E && insn_len == 4)
		  || (value == limmind && insn_len == 2))
		{
		  invalid = true;
		  break;
		}
	    }

	  if (operand->flags & ARC_OPERAND_LIMM
	      && !(operand->flags & ARC_OPERAND_DUPLICATE))
	    *has_limm = true;
	}

      /* Check the flags.  */
      for (flgidx = opcode->flags; *flgidx; flgidx++)
	{
	  /* Get a valid flag class.  */
	  const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
	  const unsigned *flgopridx;
	  int foundA = 0, foundB = 0;
	  unsigned int value;

	  /* Check first the extensions.  */
	  if (cl_flags->flag_class & F_CLASS_EXTEND)
	    {
	      value = (insn & 0x1F);
	      if (arcExtMap_condCodeName (value))
		continue;
	    }

	  /* Check for the implicit flags.  */
	  if (cl_flags->flag_class & F_CLASS_IMPLICIT)
	    continue;

	  for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
	    {
	      const struct arc_flag_operand *flg_operand =
		&arc_flag_operands[*flgopridx];

	      value = (insn >> flg_operand->shift)
		& ((1 << flg_operand->bits) - 1);
	      if (value == flg_operand->code)
		foundA = 1;
	      if (value)
		foundB = 1;
	    }

	  if (!foundA && foundB)
	    {
	      invalid = true;
	      break;
	    }
	}

      if (invalid)
	continue;

      if (insn_len == 4
	  && overlaps)
	{
	  warn_p = true;
	  t_op = opcode;
	  if (skip_this_opcode (opcode))
	    continue;
	}

      /* The instruction is valid.  */
      return opcode;
    }
  while (opcode->mask);

  if (warn_p)
    {
      info->fprintf_styled_func
	(info->stream, dis_style_text,
	 _("\nWarning: disassembly may be wrong due to "
	   "guessed opcode class choice.\n"
	   "Use -M<class[,class]> to select the correct "
	   "opcode class(es).\n\t\t\t\t"));
      return t_op;
    }

  return NULL;
}

/* Find opcode for INSN, trying various different sources.  The instruction
   length in INSN_LEN will be updated if the instruction requires a LIMM
   extension.

   A pointer to the opcode is placed into OPCODE_RESULT, and ITER is
   initialised, ready to iterate over the operands of the found opcode.  If
   the found opcode requires a LIMM then the LIMM value will be loaded into a
   field of ITER.

   This function returns TRUE in almost all cases, FALSE is reserved to
   indicate an error (failing to find an opcode is not an error) a returned
   result of FALSE would indicate that the disassembler can't continue.

   If no matching opcode is found then the returned result will be TRUE, the
   value placed into OPCODE_RESULT will be NULL, ITER will be undefined, and
   INSN_LEN will be unchanged.

   If a matching opcode is found, then the returned result will be TRUE, the
   opcode pointer is placed into OPCODE_RESULT, INSN_LEN will be increased by
   4 if the instruction requires a LIMM, and the LIMM value will have been
   loaded into a field of ITER.  Finally, ITER will have been initialised so
   that calls to OPERAND_ITERATOR_NEXT will iterate over the opcode's
   operands.  */

static bool
find_format (bfd_vma                       memaddr,
	     unsigned long long            insn,
	     unsigned int *                insn_len,
             unsigned                      isa_mask,
	     struct disassemble_info *     info,
             const struct arc_opcode **    opcode_result,
             struct arc_operand_iterator * iter)
{
  const struct arc_opcode *opcode = NULL;
  bool needs_limm = false;
  const extInstruction_t *einsn, *i;
  unsigned limm = 0;
  struct arc_disassemble_info *arc_infop = info->private_data;

  /* First, try the extension instructions.  */
  if (*insn_len == 4)
    {
      einsn = arcExtMap_insn (OPCODE_32BIT_INSN (insn), insn);
      for (i = einsn; (i != NULL) && (opcode == NULL); i = i->next)
	{
	  const char *errmsg = NULL;

	  opcode = arcExtMap_genOpcode (i, isa_mask, &errmsg);
	  if (opcode == NULL)
	    {
	      (*info->fprintf_styled_func)
		(info->stream, dis_style_text,
		 _("An error occurred while generating "
		   "the extension instruction operations"));
	      *opcode_result = NULL;
	      return false;
	    }

	  opcode = find_format_from_table (info, opcode, insn, *insn_len,
					   isa_mask, &needs_limm, false);
	}
    }

  /* Then, try finding the first match in the opcode table.  */
  if (opcode == NULL)
    opcode = find_format_from_table (info, arc_opcodes, insn, *insn_len,
				     isa_mask, &needs_limm, true);

  if (opcode != NULL && needs_limm)
    {
      bfd_byte buffer[4];
      int status;

      status = (*info->read_memory_func) (memaddr + *insn_len, buffer,
                                          4, info);
      if (status != 0)
        {
          opcode = NULL;
        }
      else
        {
          limm = ARRANGE_ENDIAN (info, buffer);
          *insn_len += 4;
        }
    }

  if (opcode != NULL)
    {
      iter->insn = insn;
      iter->limm = limm;
      iter->opcode = opcode;
      iter->opidx = opcode->operands;
    }

  *opcode_result = opcode;

  /* Update private data.  */
  arc_infop->opcode = opcode;
  arc_infop->limm = limm;
  arc_infop->limm_p = needs_limm;

  return true;
}

static void
print_flags (const struct arc_opcode *opcode,
	     unsigned long long *insn,
	     struct disassemble_info *info)
{
  const unsigned char *flgidx;
  unsigned int value;
  struct arc_disassemble_info *arc_infop = info->private_data;

  /* Now extract and print the flags.  */
  for (flgidx = opcode->flags; *flgidx; flgidx++)
    {
      /* Get a valid flag class.  */
      const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
      const unsigned *flgopridx;

      /* Check first the extensions.  */
      if (cl_flags->flag_class & F_CLASS_EXTEND)
	{
	  const char *name;
	  value = (insn[0] & 0x1F);

	  name = arcExtMap_condCodeName (value);
	  if (name)
	    {
	      (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
					    ".%s", name);
	      continue;
	    }
	}

      for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
	{
	  const struct arc_flag_operand *flg_operand =
	    &arc_flag_operands[*flgopridx];

	  /* Implicit flags are only used for the insn decoder.  */
	  if (cl_flags->flag_class & F_CLASS_IMPLICIT)
	    {
	      if (cl_flags->flag_class & F_CLASS_COND)
		arc_infop->condition_code = flg_operand->code;
	      else if (cl_flags->flag_class & F_CLASS_WB)
		arc_infop->writeback_mode = flg_operand->code;
	      else if (cl_flags->flag_class & F_CLASS_ZZ)
		info->data_size = flg_operand->code;
	      continue;
	    }

	  if (!flg_operand->favail)
	    continue;

	  value = (insn[0] >> flg_operand->shift)
	    & ((1 << flg_operand->bits) - 1);
	  if (value == flg_operand->code)
	    {
	       /* FIXME!: print correctly nt/t flag.  */
	      if (!special_flag_p (opcode->name, flg_operand->name))
		(*info->fprintf_styled_func) (info->stream,
					      dis_style_mnemonic, ".");
	      else if (info->insn_type == dis_dref)
		{
		  switch (flg_operand->name[0])
		    {
		    case 'b':
		      info->data_size = 1;
		      break;
		    case 'h':
		    case 'w':
		      info->data_size = 2;
		      break;
		    default:
		      info->data_size = 4;
		      break;
		    }
		}
	      if (flg_operand->name[0] == 'd'
		  && flg_operand->name[1] == 0)
		info->branch_delay_insns = 1;

	      /* Check if it is a conditional flag.  */
	      if (cl_flags->flag_class & F_CLASS_COND)
		{
		  if (info->insn_type == dis_jsr)
		    info->insn_type = dis_condjsr;
		  else if (info->insn_type == dis_branch)
		    info->insn_type = dis_condbranch;
		  arc_infop->condition_code = flg_operand->code;
		}

	      /* Check for the write back modes.  */
	      if (cl_flags->flag_class & F_CLASS_WB)
		arc_infop->writeback_mode = flg_operand->code;

	      (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
					    "%s", flg_operand->name);
	    }
	}
    }
}

static const char *
get_auxreg (const struct arc_opcode *opcode,
	    int value,
	    unsigned isa_mask)
{
  const char *name;
  unsigned int i;
  const struct arc_aux_reg *auxr = &arc_aux_regs[0];

  if (opcode->insn_class != AUXREG)
    return NULL;

  name = arcExtMap_auxRegName (value);
  if (name)
    return name;

  for (i = 0; i < arc_num_aux_regs; i++, auxr++)
    {
      if (!(auxr->cpu & isa_mask))
	continue;

      if (auxr->subclass != NONE)
	return NULL;

      if (auxr->address == value)
	return auxr->name;
    }
  return NULL;
}

/* Convert a value representing an address type to a string used to refer to
   the address type in assembly code.  */

static const char *
get_addrtype (int value)
{
  if (value < 0 || value > addrtypenames_max)
    return addrtypeunknown;

  return addrtypenames[value];
}

/* Calculate the instruction length for an instruction starting with MSB
   and LSB, the most and least significant byte.  The ISA_MASK is used to
   filter the instructions considered to only those that are part of the
   current architecture.

   The instruction lengths are calculated from the ARC_OPCODE table, and
   cached for later use.  */

static unsigned int
arc_insn_length (bfd_byte msb, bfd_byte lsb, struct disassemble_info *info)
{
  bfd_byte major_opcode = msb >> 3;

  switch (info->mach)
    {
    case bfd_mach_arc_arc700:
      /* The nps400 extension set requires this special casing of the
	 instruction length calculation.  Right now this is not causing any
	 problems as none of the known extensions overlap in opcode space,
	 but, if they ever do then we might need to start carrying
	 information around in the elf about which extensions are in use.  */
      if (major_opcode == 0xb)
        {
          bfd_byte minor_opcode = lsb & 0x1f;

	  if (minor_opcode < 4)
	    return 6;
	  else if (minor_opcode == 0x10 || minor_opcode == 0x11)
	    return 8;
        }
      if (major_opcode == 0xa)
        {
          return 8;
        }
      /* Fall through.  */
    case bfd_mach_arc_arc600:
      return (major_opcode > 0xb) ? 2 : 4;
      break;

    case bfd_mach_arc_arcv2:
      return (major_opcode > 0x7) ? 2 : 4;
      break;

    default:
      return 0;
    }
}

/* Extract and return the value of OPERAND from the instruction whose value
   is held in the array INSN.  */

static int
extract_operand_value (const struct arc_operand *operand,
		       unsigned long long insn,
		       unsigned limm)
{
  int value;

  /* Read the limm operand, if required.  */
  if (operand->flags & ARC_OPERAND_LIMM)
    /* The second part of the instruction value will have been loaded as
       part of the find_format call made earlier.  */
    value = limm;
  else
    {
      if (operand->extract)
	value = (*operand->extract) (insn, (bool *) NULL);
      else
        {
          if (operand->flags & ARC_OPERAND_ALIGNED32)
            {
              value = (insn >> operand->shift)
                & ((1 << (operand->bits - 2)) - 1);
              value = value << 2;
            }
          else
            {
              value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
            }
          if (operand->flags & ARC_OPERAND_SIGNED)
            {
              int signbit = 1 << (operand->bits - 1);
              value = (value ^ signbit) - signbit;
            }
        }
    }

  return value;
}

/* Find the next operand, and the operands value from ITER.  Return TRUE if
   there is another operand, otherwise return FALSE.  If there is an
   operand returned then the operand is placed into OPERAND, and the value
   into VALUE.  If there is no operand returned then OPERAND and VALUE are
   unchanged.  */

static bool
operand_iterator_next (struct arc_operand_iterator *iter,
                       const struct arc_operand **operand,
                       int *value)
{
  if (*iter->opidx == 0)
    {
      *operand = NULL;
      return false;
    }

  *operand = &arc_operands[*iter->opidx];
  *value = extract_operand_value (*operand, iter->insn, iter->limm);
  iter->opidx++;

  return true;
}

/* Helper for parsing the options.  */

static void
parse_option (const char *option)
{
  if (disassembler_options_cmp (option, "dsp") == 0)
    add_to_decodelist (DSP, NONE);

  else if (disassembler_options_cmp (option, "spfp") == 0)
    add_to_decodelist (FLOAT, SPX);

  else if (disassembler_options_cmp (option, "dpfp") == 0)
    add_to_decodelist (FLOAT, DPX);

  else if (disassembler_options_cmp (option, "quarkse_em") == 0)
    {
      add_to_decodelist (FLOAT, DPX);
      add_to_decodelist (FLOAT, SPX);
      add_to_decodelist (FLOAT, QUARKSE1);
      add_to_decodelist (FLOAT, QUARKSE2);
    }

  else if (disassembler_options_cmp (option, "fpuda") == 0)
    add_to_decodelist (FLOAT, DPA);

  else if (disassembler_options_cmp (option, "nps400") == 0)
    {
      add_to_decodelist (ACL, NPS400);
      add_to_decodelist (ARITH, NPS400);
      add_to_decodelist (BITOP, NPS400);
      add_to_decodelist (BMU, NPS400);
      add_to_decodelist (CONTROL, NPS400);
      add_to_decodelist (DMA, NPS400);
      add_to_decodelist (DPI, NPS400);
      add_to_decodelist (MEMORY, NPS400);
      add_to_decodelist (MISC, NPS400);
      add_to_decodelist (NET, NPS400);
      add_to_decodelist (PMU, NPS400);
      add_to_decodelist (PROTOCOL_DECODE, NPS400);
      add_to_decodelist (ULTRAIP, NPS400);
    }

  else if (disassembler_options_cmp (option, "fpus") == 0)
    {
      add_to_decodelist (FLOAT, SP);
      add_to_decodelist (FLOAT, CVT);
    }

  else if (disassembler_options_cmp (option, "fpud") == 0)
    {
      add_to_decodelist (FLOAT, DP);
      add_to_decodelist (FLOAT, CVT);
    }
  else if (startswith (option, "hex"))
    print_hex = true;
  else
    /* xgettext:c-format */
    opcodes_error_handler (_("unrecognised disassembler option: %s"), option);
}

#define ARC_CPU_TYPE_A6xx(NAME,EXTRA)			\
  { #NAME, ARC_OPCODE_ARC600, "ARC600" }
#define ARC_CPU_TYPE_A7xx(NAME,EXTRA)			\
  { #NAME, ARC_OPCODE_ARC700, "ARC700" }
#define ARC_CPU_TYPE_AV2EM(NAME,EXTRA)			\
  { #NAME,  ARC_OPCODE_ARCv2EM, "ARC EM" }
#define ARC_CPU_TYPE_AV2HS(NAME,EXTRA)			\
  { #NAME,  ARC_OPCODE_ARCv2HS, "ARC HS" }
#define ARC_CPU_TYPE_NONE				\
  { 0, 0, 0 }

/* A table of CPU names and opcode sets.  */
static const struct cpu_type
{
  const char *name;
  unsigned flags;
  const char *isa;
}
  cpu_types[] =
{
  #include "elf/arc-cpu.def"
};

/* Helper for parsing the CPU options.  Accept any of the ARC architectures
   values.  OPTION should be a value passed to cpu=.  */

static unsigned
parse_cpu_option (const char *option)
{
  int i;

  for (i = 0; cpu_types[i].name; ++i)
    {
      if (!disassembler_options_cmp (cpu_types[i].name, option))
	{
	  return cpu_types[i].flags;
	}
    }

  /* xgettext:c-format */
  opcodes_error_handler (_("unrecognised disassembler CPU option: %s"), option);
  return ARC_OPCODE_NONE;
}

/* Go over the options list and parse it.  */

static void
parse_disassembler_options (const char *options)
{
  const char *option;

  if (options == NULL)
    return;

  /* Disassembler might be reused for difference CPU's, and cpu option set for
     the first one shouldn't be applied to second (which might not have
     explicit cpu in its options.  Therefore it is required to reset enforced
     CPU when new options are being parsed.  */
  enforced_isa_mask = ARC_OPCODE_NONE;

  FOR_EACH_DISASSEMBLER_OPTION (option, options)
    {
      /* A CPU option?  Cannot use STRING_COMMA_LEN because strncmp is also a
	 preprocessor macro.  */
      if (strncmp (option, "cpu=", 4) == 0)
	/* Strip leading `cpu=`.  */
	enforced_isa_mask = parse_cpu_option (option + 4);
      else
	parse_option (option);
    }
}

/* Return the instruction type for an instruction described by OPCODE.  */

static enum dis_insn_type
arc_opcode_to_insn_type (const struct arc_opcode *opcode)
{
  enum dis_insn_type insn_type;

  switch (opcode->insn_class)
    {
    case BRANCH:
    case BBIT0:
    case BBIT1:
    case BI:
    case BIH:
    case BRCC:
    case EI:
    case JLI:
    case JUMP:
    case LOOP:
      if (!strncmp (opcode->name, "bl", 2)
	  || !strncmp (opcode->name, "jl", 2))
	{
	  if (opcode->subclass == COND)
	    insn_type = dis_condjsr;
	  else
	    insn_type = dis_jsr;
	}
      else
	{
	  if (opcode->subclass == COND)
	    insn_type = dis_condbranch;
	  else
	    insn_type = dis_branch;
	}
      break;
    case LOAD:
    case STORE:
    case MEMORY:
    case ENTER:
    case PUSH:
    case POP:
      insn_type = dis_dref;
      break;
    case LEAVE:
      insn_type = dis_branch;
      break;
    default:
      insn_type = dis_nonbranch;
      break;
    }

  return insn_type;
}

/* Disassemble ARC instructions.  */

static int
print_insn_arc (bfd_vma memaddr,
		struct disassemble_info *info)
{
  bfd_byte buffer[8];
  unsigned int highbyte, lowbyte;
  int status;
  unsigned int insn_len;
  unsigned long long insn = 0;
  unsigned isa_mask = ARC_OPCODE_NONE;
  const struct arc_opcode *opcode;
  bool need_comma;
  bool open_braket;
  int size;
  const struct arc_operand *operand;
  int value, vpcl;
  struct arc_operand_iterator iter;
  struct arc_disassemble_info *arc_infop;
  bool rpcl = false, rset = false;

  if (info->disassembler_options)
    {
      parse_disassembler_options (info->disassembler_options);

      /* Avoid repeated parsing of the options.  */
      info->disassembler_options = NULL;
    }

  if (info->private_data == NULL && !init_arc_disasm_info (info))
    return -1;

  memset (&iter, 0, sizeof (iter));
  highbyte  = ((info->endian == BFD_ENDIAN_LITTLE) ? 1 : 0);
  lowbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 0 : 1);

  /* Figure out CPU type, unless it was enforced via disassembler options.  */
  if (enforced_isa_mask == ARC_OPCODE_NONE)
    {
      Elf_Internal_Ehdr *header = NULL;

      if (info->section && info->section->owner)
	header = elf_elfheader (info->section->owner);

      switch (info->mach)
	{
	case bfd_mach_arc_arc700:
	  isa_mask = ARC_OPCODE_ARC700;
	  break;

	case bfd_mach_arc_arc600:
	  isa_mask = ARC_OPCODE_ARC600;
	  break;

	case bfd_mach_arc_arcv2:
	default:
	  isa_mask = ARC_OPCODE_ARCv2EM;
	  /* TODO: Perhaps remove definition of header since it is only used at
	     this location.  */
	  if (header != NULL
	      && (header->e_flags & EF_ARC_MACH_MSK) == EF_ARC_CPU_ARCV2HS)
	    isa_mask = ARC_OPCODE_ARCv2HS;
	  break;
	}
    }
  else
    isa_mask = enforced_isa_mask;

  if (isa_mask == ARC_OPCODE_ARCv2HS)
    {
      /* FPU instructions are not extensions for HS.  */
      add_to_decodelist (FLOAT, SP);
      add_to_decodelist (FLOAT, DP);
      add_to_decodelist (FLOAT, CVT);
    }

  /* This variable may be set by the instruction decoder.  It suggests
     the number of bytes objdump should display on a single line.  If
     the instruction decoder sets this, it should always set it to
     the same value in order to get reasonable looking output.  */
  info->bytes_per_line  = 8;

  /* In the next lines, we set two info variables control the way
     objdump displays the raw data.  For example, if bytes_per_line is
     8 and bytes_per_chunk is 4, the output will look like this:
     00:   00000000 00000000
     with the chunks displayed according to "display_endian".  */
  if (info->section
      && !(info->section->flags & SEC_CODE))
    {
      /* This is not a CODE section.  */
      switch (info->section->size)
	{
	case 1:
	case 2:
	case 4:
	  size = info->section->size;
	  break;
	default:
	  size = (info->section->size & 0x01) ? 1 : 4;
	  break;
	}
      info->bytes_per_chunk = 1;
      info->display_endian = info->endian;
    }
  else
    {
      size = 2;
      info->bytes_per_chunk = 2;
      info->display_endian = info->endian;
    }

  /* Read the insn into a host word.  */
  status = (*info->read_memory_func) (memaddr, buffer, size, info);

  if (status != 0)
    {
      (*info->memory_error_func) (status, memaddr, info);
      return -1;
    }

  if (info->section
      && !(info->section->flags & SEC_CODE))
    {
      /* Data section.  */
      unsigned long data;

      data = bfd_get_bits (buffer, size * 8,
			   info->display_endian == BFD_ENDIAN_BIG);
      switch (size)
	{
	case 1:
	  (*info->fprintf_styled_func) (info->stream,
					dis_style_assembler_directive,
					".byte");
	  (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
	  (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
					"0x%02lx", data);
	  break;
	case 2:
	  (*info->fprintf_styled_func) (info->stream,
					dis_style_assembler_directive,
					".short");
	  (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
	  (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
					"0x%04lx", data);
	  break;
	case 4:
	  (*info->fprintf_styled_func) (info->stream,
					dis_style_assembler_directive,
					".word");
	  (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
	  (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
					"0x%08lx", data);
	  break;
	default:
	  return -1;
	}
      return size;
    }

  insn_len = arc_insn_length (buffer[highbyte], buffer[lowbyte], info);
  pr_debug ("instruction length = %d bytes\n", insn_len);
  if (insn_len == 0)
    return -1;

  arc_infop = info->private_data;
  arc_infop->insn_len = insn_len;

  switch (insn_len)
    {
    case 2:
      insn = (buffer[highbyte] << 8) | buffer[lowbyte];
      break;

    case 4:
      {
	/* This is a long instruction: Read the remaning 2 bytes.  */
	status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 2, info);
	if (status != 0)
	  {
	    (*info->memory_error_func) (status, memaddr + 2, info);
	    return -1;
	  }
	insn = (unsigned long long) ARRANGE_ENDIAN (info, buffer);
      }
      break;

    case 6:
      {
	status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 4, info);
	if (status != 0)
	  {
	    (*info->memory_error_func) (status, memaddr + 2, info);
	    return -1;
	  }
	insn = (unsigned long long) ARRANGE_ENDIAN (info, &buffer[2]);
	insn |= ((unsigned long long) buffer[highbyte] << 40)
	  | ((unsigned long long) buffer[lowbyte] << 32);
      }
      break;

    case 8:
      {
	status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 6, info);
	if (status != 0)
	  {
	    (*info->memory_error_func) (status, memaddr + 2, info);
	    return -1;
	  }
	insn =
	  ((((unsigned long long) ARRANGE_ENDIAN (info, buffer)) << 32)
	   | ((unsigned long long) ARRANGE_ENDIAN (info, &buffer[4])));
      }
      break;

    default:
      /* There is no instruction whose length is not 2, 4, 6, or 8.  */
      return -1;
    }

  pr_debug ("instruction value = %llx\n", insn);

  /* Set some defaults for the insn info.  */
  info->insn_info_valid    = 1;
  info->branch_delay_insns = 0;
  info->data_size	   = 4;
  info->insn_type	   = dis_nonbranch;
  info->target		   = 0;
  info->target2		   = 0;

  /* FIXME to be moved in dissasemble_init_for_target.  */
  info->disassembler_needs_relocs = true;

  /* Find the first match in the opcode table.  */
  if (!find_format (memaddr, insn, &insn_len, isa_mask, info, &opcode, &iter))
    return -1;

  if (!opcode)
    {
      switch (insn_len)
	{
	case 2:
	  (*info->fprintf_styled_func) (info->stream,
					dis_style_assembler_directive,
					".short");
	  (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
	  (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
					"0x%04llx", insn & 0xffff);
	  break;

	case 4:
	  (*info->fprintf_styled_func) (info->stream,
					dis_style_assembler_directive,
					".word");
	  (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
	  (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
					"0x%08llx", insn & 0xffffffff);
	  break;

	case 6:
	  (*info->fprintf_styled_func) (info->stream,
					dis_style_assembler_directive,
					".long");
	  (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
	  (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
				       "0x%08llx", insn & 0xffffffff);
	  (*info->fprintf_styled_func) (info->stream, dis_style_text, " ");
	  (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
					"0x%04llx", (insn >> 32) & 0xffff);
	  break;

	case 8:
	  (*info->fprintf_styled_func) (info->stream,
					dis_style_assembler_directive,
					".long");
	  (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");
	  (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
					"0x%08llx", insn & 0xffffffff);
	  (*info->fprintf_styled_func) (info->stream, dis_style_text, " ");
	  (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
					"0x%08llx", (insn >> 32));
	  break;

	default:
	  return -1;
	}

      info->insn_type = dis_noninsn;
      return insn_len;
    }

  /* Print the mnemonic.  */
  (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
				"%s", opcode->name);

  /* Preselect the insn class.  */
  info->insn_type = arc_opcode_to_insn_type (opcode);

  pr_debug ("%s: 0x%08llx\n", opcode->name, opcode->opcode);

  print_flags (opcode, &insn, info);

  if (opcode->operands[0] != 0)
    (*info->fprintf_styled_func) (info->stream, dis_style_text, "\t");

  need_comma = false;
  open_braket = false;
  arc_infop->operands_count = 0;

  /* Now extract and print the operands.  */
  operand = NULL;
  vpcl = 0;
  while (operand_iterator_next (&iter, &operand, &value))
    {
      if (open_braket && (operand->flags & ARC_OPERAND_BRAKET))
	{
	  (*info->fprintf_styled_func) (info->stream, dis_style_text, "]");
	  open_braket = false;
	  continue;
	}

      /* Only take input from real operands.  */
      if (ARC_OPERAND_IS_FAKE (operand))
	continue;

      if ((operand->flags & ARC_OPERAND_IGNORE)
	  && (operand->flags & ARC_OPERAND_IR)
	  && value == -1)
	continue;

      if (operand->flags & ARC_OPERAND_COLON)
	{
	  (*info->fprintf_styled_func) (info->stream, dis_style_text, ":");
	  continue;
	}

      if (need_comma)
	(*info->fprintf_styled_func) (info->stream, dis_style_text,",");

      if (!open_braket && (operand->flags & ARC_OPERAND_BRAKET))
	{
	  (*info->fprintf_styled_func) (info->stream, dis_style_text, "[");
	  open_braket = true;
	  need_comma = false;
	  continue;
	}

      need_comma = true;

      if (operand->flags & ARC_OPERAND_PCREL)
	{
	  rpcl = true;
	  vpcl = value;
	  rset = true;

	  info->target = (bfd_vma) (memaddr & ~3) + value;
	}
      else if (!(operand->flags & ARC_OPERAND_IR))
	{
	  vpcl = value;
	  rset = true;
	}

      /* Print the operand as directed by the flags.  */
      if (operand->flags & ARC_OPERAND_IR)
	{
	  const char *rname;

	  assert (value >=0 && value < 64);
	  rname = arcExtMap_coreRegName (value);
	  if (!rname)
	    rname = regnames[value];
	  (*info->fprintf_styled_func) (info->stream, dis_style_register,
					"%s", rname);

	  /* Check if we have a double register to print.  */
	  if (operand->flags & ARC_OPERAND_TRUNCATE)
	    {
	      if ((value & 0x01) == 0)
		{
		  rname = arcExtMap_coreRegName (value + 1);
		  if (!rname)
		    rname = regnames[value + 1];
		}
	      else
		rname = _("\nWarning: illegal use of double register "
			  "pair.\n");
	      (*info->fprintf_styled_func) (info->stream, dis_style_register,
					    "%s", rname);
	    }
	  if (value == 63)
	    rpcl = true;
	  else
	    rpcl = false;
	}
      else if (operand->flags & ARC_OPERAND_LIMM)
	{
	  const char *rname = get_auxreg (opcode, value, isa_mask);

	  if (rname && open_braket)
	    (*info->fprintf_styled_func) (info->stream, dis_style_register,
					  "%s", rname);
	  else
	    {
	      (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
					    "%#x", value);
	      if (info->insn_type == dis_branch
		  || info->insn_type == dis_jsr)
		info->target = (bfd_vma) value;
	    }
	}
      else if (operand->flags & ARC_OPERAND_SIGNED)
	{
	  const char *rname = get_auxreg (opcode, value, isa_mask);
	  if (rname && open_braket)
	    (*info->fprintf_styled_func) (info->stream, dis_style_register,
					  "%s", rname);
	  else
	    {
	      if (print_hex)
		(*info->fprintf_styled_func) (info->stream, dis_style_immediate,
					      "%#x", value);
	      else
		(*info->fprintf_styled_func) (info->stream, dis_style_immediate,
					      "%d", value);
	    }
	}
      else if (operand->flags & ARC_OPERAND_ADDRTYPE)
	{
	  const char *addrtype = get_addrtype (value);
	  (*info->fprintf_styled_func) (info->stream, dis_style_address,
					"%s", addrtype);
	  /* A colon follow an address type.  */
	  need_comma = false;
	}
      else
	{
	  if (operand->flags & ARC_OPERAND_TRUNCATE
	      && !(operand->flags & ARC_OPERAND_ALIGNED32)
	      && !(operand->flags & ARC_OPERAND_ALIGNED16)
	      && value >= 0 && value <= 14)
	    {
	      /* Leave/Enter mnemonics.  */
	      switch (value)
		{
		case 0:
		  need_comma = false;
		  break;
		case 1:
		  (*info->fprintf_styled_func) (info->stream,
						dis_style_register, "r13");
		  break;
		default:
		  (*info->fprintf_styled_func) (info->stream,
						dis_style_register, "r13");
		  (*info->fprintf_styled_func) (info->stream,
						dis_style_text, "-");
		  (*info->fprintf_styled_func) (info->stream,
						dis_style_register, "%s",
						regnames[13 + value - 1]);
		  break;
		}
	      rpcl = false;
	      rset = false;
	    }
	  else
	    {
	      const char *rname = get_auxreg (opcode, value, isa_mask);
	      if (rname && open_braket)
		(*info->fprintf_styled_func) (info->stream, dis_style_register,
					      "%s", rname);
	      else
		(*info->fprintf_styled_func) (info->stream, dis_style_immediate,
					      "%#x", value);
	    }
	}

      if (operand->flags & ARC_OPERAND_LIMM)
	{
	  arc_infop->operands[arc_infop->operands_count].kind
	    = ARC_OPERAND_KIND_LIMM;
	  /* It is not important to have exactly the LIMM indicator
	     here.  */
	  arc_infop->operands[arc_infop->operands_count].value = 63;
	}
      else
	{
	  arc_infop->operands[arc_infop->operands_count].value = value;
	  arc_infop->operands[arc_infop->operands_count].kind
	    = (operand->flags & ARC_OPERAND_IR
	       ? ARC_OPERAND_KIND_REG
	       : ARC_OPERAND_KIND_SHIMM);
	}
      arc_infop->operands_count ++;
    }

  /* Pretty print extra info for pc-relative operands.  */
  if (rpcl && rset)
    {
      if (info->flags & INSN_HAS_RELOC)
	/* If the instruction has a reloc associated with it, then the
	   offset field in the instruction will actually be the addend
	   for the reloc.  (We are using REL type relocs).  In such
	   cases, we can ignore the pc when computing addresses, since
	   the addend is not currently pc-relative.  */
	memaddr = 0;

      (*info->fprintf_styled_func) (info->stream,
				    dis_style_comment_start, "\t;");
      (*info->print_address_func) ((memaddr & ~3) + vpcl, info);
    }

  return insn_len;
}


disassembler_ftype
arc_get_disassembler (bfd *abfd)
{
  /* BFD my be absent, if opcodes is invoked from the debugger that
     has connected to remote target and doesn't have an ELF file.  */
  if (abfd != NULL)
    {
      /* Read the extension insns and registers, if any.  */
      build_ARC_extmap (abfd);
#ifdef DEBUG
      dump_ARC_extmap ();
#endif
    }

  return print_insn_arc;
}

/* Indices into option argument vector for options that do require
   an argument.  Use ARC_OPTION_ARG_NONE for options that don't
   expect an argument.  */
typedef enum
{
  ARC_OPTION_ARG_NONE = -1,
  ARC_OPTION_ARG_ARCH,
  ARC_OPTION_ARG_SIZE
} arc_option_arg_t;

/* Valid ARC disassembler options.  */
static struct
{
  const char *name;
  const char *description;
  arc_option_arg_t arg;
} arc_options[] =
{
  { "cpu=",       N_("Enforce the designated architecture while decoding."),
		  ARC_OPTION_ARG_ARCH },
  { "dsp",	  N_("Recognize DSP instructions."),
		  ARC_OPTION_ARG_NONE },
  { "spfp",	  N_("Recognize FPX SP instructions."),
		  ARC_OPTION_ARG_NONE },
  { "dpfp",	  N_("Recognize FPX DP instructions."),
		  ARC_OPTION_ARG_NONE },
  { "quarkse_em", N_("Recognize FPU QuarkSE-EM instructions."),
		  ARC_OPTION_ARG_NONE },
  { "fpuda",	  N_("Recognize double assist FPU instructions."),
		  ARC_OPTION_ARG_NONE },
  { "fpus",	  N_("Recognize single precision FPU instructions."),
		  ARC_OPTION_ARG_NONE },
  { "fpud",	  N_("Recognize double precision FPU instructions."),
		  ARC_OPTION_ARG_NONE },
  { "nps400",	  N_("Recognize NPS400 instructions."),
		  ARC_OPTION_ARG_NONE },
  { "hex",	  N_("Use only hexadecimal number to print immediates."),
		  ARC_OPTION_ARG_NONE }
};

/* Populate the structure for representing ARC's disassembly options.
   Such a dynamic initialization is desired, because it makes the maintenance
   easier and also gdb uses this to enable the "disassembler-option".  */

const disasm_options_and_args_t *
disassembler_options_arc (void)
{
  static disasm_options_and_args_t *opts_and_args;

  if (opts_and_args == NULL)
    {
      disasm_option_arg_t *args;
      disasm_options_t *opts;
      size_t i;
      const size_t nr_of_options = ARRAY_SIZE (arc_options);
      /* There is a null element at the end of CPU_TYPES, therefore
	 NR_OF_CPUS is actually 1 more and that is desired here too.  */
      const size_t nr_of_cpus = ARRAY_SIZE (cpu_types);

      opts_and_args = XNEW (disasm_options_and_args_t);
      opts_and_args->args
	= XNEWVEC (disasm_option_arg_t, ARC_OPTION_ARG_SIZE + 1);
      opts_and_args->options.name
	= XNEWVEC (const char *, nr_of_options + 1);
      opts_and_args->options.description
	= XNEWVEC (const char *, nr_of_options + 1);
      opts_and_args->options.arg
	= XNEWVEC (const disasm_option_arg_t *, nr_of_options + 1);

      /* Populate the arguments for "cpu=" option.  */
      args = opts_and_args->args;
      args[ARC_OPTION_ARG_ARCH].name = "ARCH";
      args[ARC_OPTION_ARG_ARCH].values = XNEWVEC (const char *, nr_of_cpus);
      for (i = 0; i < nr_of_cpus; ++i)
	args[ARC_OPTION_ARG_ARCH].values[i] = cpu_types[i].name;
      args[ARC_OPTION_ARG_SIZE].name = NULL;
      args[ARC_OPTION_ARG_SIZE].values = NULL;

      /* Populate the options.  */
      opts = &opts_and_args->options;
      for (i = 0; i < nr_of_options; ++i)
	{
	  opts->name[i] = arc_options[i].name;
	  opts->description[i] = arc_options[i].description;
	  if (arc_options[i].arg != ARC_OPTION_ARG_NONE)
	    opts->arg[i] = &args[arc_options[i].arg];
	  else
	    opts->arg[i] = NULL;
	}
      opts->name[nr_of_options] = NULL;
      opts->description[nr_of_options] = NULL;
      opts->arg[nr_of_options] = NULL;
    }

  return opts_and_args;
}


void
print_arc_disassembler_options (FILE *stream)
{
  const disasm_options_and_args_t *opts_and_args;
  const disasm_option_arg_t *args;
  const disasm_options_t *opts;
  size_t i, j;
  size_t max_len = 0;

  opts_and_args = disassembler_options_arc ();
  opts = &opts_and_args->options;
  args = opts_and_args->args;

  fprintf (stream, _("\nThe following ARC specific disassembler options are"
		     " supported for use \nwith the -M switch (multiple"
		     " options should be separated by commas):\n"));

  /* Find the maximum length for printing options (and their arg name).  */
  for (i = 0; opts->name[i] != NULL; ++i)
    {
      size_t len = strlen (opts->name[i]);
      len += (opts->arg[i]) ? strlen (opts->arg[i]->name) : 0;
      max_len = (len > max_len) ? len : max_len;
    }

  /* Print the options, their arg and description, if any.  */
  for (i = 0, ++max_len; opts->name[i] != NULL; ++i)
    {
      fprintf (stream, "  %s", opts->name[i]);
      if (opts->arg[i] != NULL)
	fprintf (stream, "%s", opts->arg[i]->name);
      if (opts->description[i] != NULL)
	{
	  size_t len = strlen (opts->name[i]);
	  len += (opts->arg[i]) ? strlen (opts->arg[i]->name) : 0;
	  fprintf (stream,
		   "%*c %s", (int) (max_len - len), ' ', opts->description[i]);
	}
      fprintf (stream, _("\n"));
    }

  /* Print the possible values of an argument.  */
  for (i = 0; args[i].name != NULL; ++i)
    {
      size_t len = 3;
      fprintf (stream, _("\n\
  For the options above, the following values are supported for \"%s\":\n   "),
	       args[i].name);
      for (j = 0; args[i].values[j] != NULL; ++j)
	{
	  fprintf (stream, " %s", args[i].values[j]);
	  len += strlen (args[i].values[j]) + 1;
	  /* reset line if printed too long.  */
	  if (len >= 78)
	    {
	      fprintf (stream, _("\n   "));
	      len = 3;
	    }
	}
      fprintf (stream, _("\n"));
    }

  fprintf (stream, _("\n"));
}

void arc_insn_decode (bfd_vma addr,
		      struct disassemble_info *info,
		      disassembler_ftype disasm_func,
		      struct arc_instruction *insn)
{
  const struct arc_opcode *opcode;
  struct arc_disassemble_info *arc_infop;

  /* Ensure that insn would be in the reset state.  */
  memset (insn, 0, sizeof (struct arc_instruction));

  /* There was an error when disassembling, for example memory read error.  */
  if (disasm_func (addr, info) < 0)
    {
      insn->valid = false;
      return;
    }

  assert (info->private_data != NULL);
  arc_infop = info->private_data;

  insn->length  = arc_infop->insn_len;;
  insn->address = addr;

  /* Quick exit if memory at this address is not an instruction.  */
  if (info->insn_type == dis_noninsn)
    {
      insn->valid = false;
      return;
    }

  insn->valid = true;

  opcode = (const struct arc_opcode *) arc_infop->opcode;
  insn->insn_class = opcode->insn_class;
  insn->limm_value = arc_infop->limm;
  insn->limm_p     = arc_infop->limm_p;

  insn->is_control_flow = (info->insn_type == dis_branch
			   || info->insn_type == dis_condbranch
			   || info->insn_type == dis_jsr
			   || info->insn_type == dis_condjsr);

  insn->has_delay_slot = info->branch_delay_insns;
  insn->writeback_mode
    = (enum arc_ldst_writeback_mode) arc_infop->writeback_mode;
  insn->data_size_mode = info->data_size;
  insn->condition_code = arc_infop->condition_code;
  memcpy (insn->operands, arc_infop->operands,
	  sizeof (struct arc_insn_operand) * MAX_INSN_ARGS);
  insn->operands_count = arc_infop->operands_count;
}

/* Local variables:
   eval: (c-set-style "gnu")
   indent-tabs-mode: t
   End:  */
