/* Instruction printing code for the ARC.
   Copyright (C) 1994-2020 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.  */
  bfd_boolean 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 bfd_boolean 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 bfd_boolean
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 bfd_boolean
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 bfd_boolean
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,
			bfd_boolean *has_limm,
			bfd_boolean 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;
  bfd_boolean warn_p = FALSE;

  do
    {
      bfd_boolean 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_func (info->stream,
			  _("\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 bfd_boolean
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;
  bfd_boolean needs_limm;
  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_func) (info->stream, "\
An error occured 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 (needs_limm && opcode != NULL)
    {
      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 = (needs_limm) ? limm : 0;
  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_func) (info->stream, ".%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_func) (info->stream, ".");
	      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_func) (info->stream, "%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, (int *) 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 bfd_boolean
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 (CONST_STRNEQ (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;
  bfd_boolean need_comma;
  bfd_boolean open_braket;
  int size;
  const struct arc_operand *operand;
  int value, vpcl;
  struct arc_operand_iterator iter;
  struct arc_disassemble_info *arc_infop;
  bfd_boolean 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_func) (info->stream, ".byte\t0x%02lx", data);
	  break;
	case 2:
	  (*info->fprintf_func) (info->stream, ".short\t0x%04lx", data);
	  break;
	case 4:
	  (*info->fprintf_func) (info->stream, ".word\t0x%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_func) (info->stream, ".shor\t%#04llx",
				 insn & 0xffff);
	  break;

	case 4:
	  (*info->fprintf_func) (info->stream, ".word\t%#08llx",
				 insn & 0xffffffff);
	  break;

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

	case 8:
	  (*info->fprintf_func) (info->stream, ".long\t%#08llx",
				 insn & 0xffffffff);
	  (*info->fprintf_func) (info->stream, ".long\t%#08llx",
				 insn >> 32);
	  break;

	default:
	  return -1;
	}

      info->insn_type = dis_noninsn;
      return insn_len;
    }

  /* Print the mnemonic.  */
  (*info->fprintf_func) (info->stream, "%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_func) (info->stream, "\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_func) (info->stream, "]");
	  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_func) (info->stream, ":");
	  continue;
	}

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

      if (!open_braket && (operand->flags & ARC_OPERAND_BRAKET))
	{
	  (*info->fprintf_func) (info->stream, "[");
	  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_func) (info->stream, "%s", rname);
	  if (operand->flags & ARC_OPERAND_TRUNCATE)
	    {
	      rname = arcExtMap_coreRegName (value + 1);
	      if (!rname)
		rname = regnames[value + 1];
	      (*info->fprintf_func) (info->stream, "%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_func) (info->stream, "%s", rname);
	  else
	    {
	      (*info->fprintf_func) (info->stream, "%#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_func) (info->stream, "%s", rname);
	  else
	    {
	      if (print_hex)
		(*info->fprintf_func) (info->stream, "%#x", value);
	      else
		(*info->fprintf_func) (info->stream, "%d", value);
	    }
	}
      else if (operand->flags & ARC_OPERAND_ADDRTYPE)
	{
	  const char *addrtype = get_addrtype (value);
	  (*info->fprintf_func) (info->stream, "%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_func) (info->stream, "r13");
		  break;
		default:
		  (*info->fprintf_func) (info->stream, "r13-%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_func) (info->stream, "%s", rname);
	      else
		(*info->fprintf_func) (info->stream, "%#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_func) (info->stream, "\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;
}

void
print_arc_disassembler_options (FILE *stream)
{
  int i;

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

  /* cpu=... options.  */
  for (i = 0; cpu_types[i].name; ++i)
    {
      /* As of now all value CPU values are less than 16 characters.  */
      fprintf (stream, "  cpu=%-16s\tEnforce %s ISA.\n",
	       cpu_types[i].name, cpu_types[i].isa);
    }

  fprintf (stream, _("\
  dsp             Recognize DSP instructions.\n"));
  fprintf (stream, _("\
  spfp            Recognize FPX SP instructions.\n"));
  fprintf (stream, _("\
  dpfp            Recognize FPX DP instructions.\n"));
  fprintf (stream, _("\
  quarkse_em      Recognize FPU QuarkSE-EM instructions.\n"));
  fprintf (stream, _("\
  fpuda           Recognize double assist FPU instructions.\n"));
  fprintf (stream, _("\
  fpus            Recognize single precision FPU instructions.\n"));
  fprintf (stream, _("\
  fpud            Recognize double precision FPU instructions.\n"));
  fprintf (stream, _("\
  nps400          Recognize NPS400 instructions.\n"));
  fprintf (stream, _("\
  hex             Use only hexadecimal number to print immediates.\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:  */
