Home | History | Annotate | Line # | Download | only in opcodes
arc-dis.c revision 1.1.1.6
      1 /* Instruction printing code for the ARC.
      2    Copyright (C) 1994-2020 Free Software Foundation, Inc.
      3 
      4    Contributed by Claudiu Zissulescu (claziss (at) synopsys.com)
      5 
      6    This file is part of libopcodes.
      7 
      8    This library is free software; you can redistribute it and/or modify
      9    it under the terms of the GNU General Public License as published by
     10    the Free Software Foundation; either version 3, or (at your option)
     11    any later version.
     12 
     13    It is distributed in the hope that it will be useful, but WITHOUT
     14    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     15    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     16    License for more details.
     17 
     18    You should have received a copy of the GNU General Public License
     19    along with this program; if not, write to the Free Software
     20    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     21    MA 02110-1301, USA.  */
     22 
     23 #include "sysdep.h"
     24 #include <stdio.h>
     25 #include <assert.h>
     26 #include "dis-asm.h"
     27 #include "opcode/arc.h"
     28 #include "elf/arc.h"
     29 #include "arc-dis.h"
     30 #include "arc-ext.h"
     31 #include "elf-bfd.h"
     32 #include "libiberty.h"
     33 #include "opintl.h"
     34 
     35 /* Structure used to iterate over, and extract the values for, operands of
     36    an opcode.  */
     37 
     38 struct arc_operand_iterator
     39 {
     40   /* The complete instruction value to extract operands from.  */
     41   unsigned long long insn;
     42 
     43   /* The LIMM if this is being tracked separately.  This field is only
     44      valid if we find the LIMM operand in the operand list.  */
     45   unsigned limm;
     46 
     47   /* The opcode this iterator is operating on.  */
     48   const struct arc_opcode *opcode;
     49 
     50   /* The index into the opcodes operand index list.  */
     51   const unsigned char *opidx;
     52 };
     53 
     54 /* A private data used by ARC decoder.  */
     55 struct arc_disassemble_info
     56 {
     57   /* The current disassembled arc opcode.  */
     58   const struct arc_opcode *opcode;
     59 
     60   /* Instruction length w/o limm field.  */
     61   unsigned insn_len;
     62 
     63   /* TRUE if we have limm.  */
     64   bfd_boolean limm_p;
     65 
     66   /* LIMM value, if exists.  */
     67   unsigned limm;
     68 
     69   /* Condition code, if exists.  */
     70   unsigned condition_code;
     71 
     72   /* Writeback mode.  */
     73   unsigned writeback_mode;
     74 
     75   /* Number of operands.  */
     76   unsigned operands_count;
     77 
     78   struct arc_insn_operand operands[MAX_INSN_ARGS];
     79 };
     80 
     81 /* Globals variables.  */
     82 
     83 static const char * const regnames[64] =
     84 {
     85   "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
     86   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
     87   "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
     88   "r24", "r25", "gp", "fp", "sp", "ilink", "r30", "blink",
     89 
     90   "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
     91   "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
     92   "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",
     93   "r56", "r57", "r58", "r59", "lp_count", "reserved", "LIMM", "pcl"
     94 };
     95 
     96 static const char * const addrtypenames[ARC_NUM_ADDRTYPES] =
     97 {
     98   "bd", "jid", "lbd", "mbd", "sd", "sm", "xa", "xd",
     99   "cd", "cbd", "cjid", "clbd", "cm", "csd", "cxa", "cxd"
    100 };
    101 
    102 static int addrtypenames_max = ARC_NUM_ADDRTYPES - 1;
    103 
    104 static const char * const addrtypeunknown = "unknown";
    105 
    106 /* This structure keeps track which instruction class(es)
    107    should be ignored durring disassembling.  */
    108 
    109 typedef struct skipclass
    110 {
    111   insn_class_t     insn_class;
    112   insn_subclass_t  subclass;
    113   struct skipclass *nxt;
    114 } skipclass_t, *linkclass;
    115 
    116 /* Intial classes of instructions to be consider first when
    117    disassembling.  */
    118 static linkclass decodelist = NULL;
    119 
    120 /* ISA mask value enforced via disassembler info options.  ARC_OPCODE_NONE
    121    value means that no CPU is enforced.  */
    122 
    123 static unsigned enforced_isa_mask = ARC_OPCODE_NONE;
    124 
    125 /* True if we want to print using only hex numbers.  */
    126 static bfd_boolean print_hex = FALSE;
    127 
    128 /* Macros section.  */
    129 
    130 #ifdef DEBUG
    131 # define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args)
    132 #else
    133 # define pr_debug(fmt, args...)
    134 #endif
    135 
    136 #define ARRANGE_ENDIAN(info, buf)					\
    137   (info->endian == BFD_ENDIAN_LITTLE ? bfd_getm32 (bfd_getl32 (buf))	\
    138    : bfd_getb32 (buf))
    139 
    140 #define BITS(word,s,e)  (((word) >> (s)) & ((1ull << ((e) - (s)) << 1) - 1))
    141 #define OPCODE_32BIT_INSN(word)	(BITS ((word), 27, 31))
    142 
    143 /* Functions implementation.  */
    144 
    145 /* Initialize private data.  */
    146 static bfd_boolean
    147 init_arc_disasm_info (struct disassemble_info *info)
    148 {
    149   struct arc_disassemble_info *arc_infop
    150     = calloc (sizeof (*arc_infop), 1);
    151 
    152   if (arc_infop == NULL)
    153     return FALSE;
    154 
    155   info->private_data = arc_infop;
    156   return TRUE;
    157 }
    158 
    159 /* Add a new element to the decode list.  */
    160 
    161 static void
    162 add_to_decodelist (insn_class_t     insn_class,
    163 		   insn_subclass_t  subclass)
    164 {
    165   linkclass t = (linkclass) xmalloc (sizeof (skipclass_t));
    166 
    167   t->insn_class = insn_class;
    168   t->subclass = subclass;
    169   t->nxt = decodelist;
    170   decodelist = t;
    171 }
    172 
    173 /* Return TRUE if we need to skip the opcode from being
    174    disassembled.  */
    175 
    176 static bfd_boolean
    177 skip_this_opcode (const struct arc_opcode *opcode)
    178 {
    179   linkclass t = decodelist;
    180 
    181   /* Check opcode for major 0x06, return if it is not in.  */
    182   if (arc_opcode_len (opcode) == 4
    183       && (OPCODE_32BIT_INSN (opcode->opcode) != 0x06
    184 	  /* Can be an APEX extensions.  */
    185 	  && OPCODE_32BIT_INSN (opcode->opcode) != 0x07))
    186     return FALSE;
    187 
    188   /* or not a known truble class.  */
    189   switch (opcode->insn_class)
    190     {
    191     case FLOAT:
    192     case DSP:
    193     case ARITH:
    194     case MPY:
    195       break;
    196     default:
    197       return FALSE;
    198     }
    199 
    200   while (t != NULL)
    201     {
    202       if ((t->insn_class == opcode->insn_class)
    203 	  && (t->subclass == opcode->subclass))
    204 	return FALSE;
    205       t = t->nxt;
    206     }
    207 
    208   return TRUE;
    209 }
    210 
    211 static bfd_vma
    212 bfd_getm32 (unsigned int data)
    213 {
    214   bfd_vma value = 0;
    215 
    216   value = ((data & 0xff00) | (data & 0xff)) << 16;
    217   value |= ((data & 0xff0000) | (data & 0xff000000)) >> 16;
    218   return value;
    219 }
    220 
    221 static bfd_boolean
    222 special_flag_p (const char *opname,
    223 		const char *flgname)
    224 {
    225   const struct arc_flag_special *flg_spec;
    226   unsigned i, j, flgidx;
    227 
    228   for (i = 0; i < arc_num_flag_special; i++)
    229     {
    230       flg_spec = &arc_flag_special_cases[i];
    231 
    232       if (strcmp (opname, flg_spec->name))
    233 	continue;
    234 
    235       /* Found potential special case instruction.  */
    236       for (j=0;; ++j)
    237 	{
    238 	  flgidx = flg_spec->flags[j];
    239 	  if (flgidx == 0)
    240 	    break; /* End of the array.  */
    241 
    242 	  if (strcmp (flgname, arc_flag_operands[flgidx].name) == 0)
    243 	    return TRUE;
    244 	}
    245     }
    246   return FALSE;
    247 }
    248 
    249 /* Find opcode from ARC_TABLE given the instruction described by INSN and
    250    INSNLEN.  The ISA_MASK restricts the possible matches in ARC_TABLE.  */
    251 
    252 static const struct arc_opcode *
    253 find_format_from_table (struct disassemble_info *info,
    254 			const struct arc_opcode *arc_table,
    255                         unsigned long long insn,
    256 			unsigned int insn_len,
    257                         unsigned isa_mask,
    258 			bfd_boolean *has_limm,
    259 			bfd_boolean overlaps)
    260 {
    261   unsigned int i = 0;
    262   const struct arc_opcode *opcode = NULL;
    263   const struct arc_opcode *t_op = NULL;
    264   const unsigned char *opidx;
    265   const unsigned char *flgidx;
    266   bfd_boolean warn_p = FALSE;
    267 
    268   do
    269     {
    270       bfd_boolean invalid = FALSE;
    271 
    272       opcode = &arc_table[i++];
    273 
    274       if (!(opcode->cpu & isa_mask))
    275 	continue;
    276 
    277       if (arc_opcode_len (opcode) != (int) insn_len)
    278 	continue;
    279 
    280       if ((insn & opcode->mask) != opcode->opcode)
    281 	continue;
    282 
    283       *has_limm = FALSE;
    284 
    285       /* Possible candidate, check the operands.  */
    286       for (opidx = opcode->operands; *opidx; opidx++)
    287 	{
    288 	  int value, limmind;
    289 	  const struct arc_operand *operand = &arc_operands[*opidx];
    290 
    291 	  if (operand->flags & ARC_OPERAND_FAKE)
    292 	    continue;
    293 
    294 	  if (operand->extract)
    295 	    value = (*operand->extract) (insn, &invalid);
    296 	  else
    297 	    value = (insn >> operand->shift) & ((1ull << operand->bits) - 1);
    298 
    299 	  /* Check for LIMM indicator.  If it is there, then make sure
    300 	     we pick the right format.  */
    301 	  limmind = (isa_mask & ARC_OPCODE_ARCV2) ? 0x1E : 0x3E;
    302 	  if (operand->flags & ARC_OPERAND_IR
    303 	      && !(operand->flags & ARC_OPERAND_LIMM))
    304 	    {
    305 	      if ((value == 0x3E && insn_len == 4)
    306 		  || (value == limmind && insn_len == 2))
    307 		{
    308 		  invalid = TRUE;
    309 		  break;
    310 		}
    311 	    }
    312 
    313 	  if (operand->flags & ARC_OPERAND_LIMM
    314 	      && !(operand->flags & ARC_OPERAND_DUPLICATE))
    315 	    *has_limm = TRUE;
    316 	}
    317 
    318       /* Check the flags.  */
    319       for (flgidx = opcode->flags; *flgidx; flgidx++)
    320 	{
    321 	  /* Get a valid flag class.  */
    322 	  const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
    323 	  const unsigned *flgopridx;
    324 	  int foundA = 0, foundB = 0;
    325 	  unsigned int value;
    326 
    327 	  /* Check first the extensions.  */
    328 	  if (cl_flags->flag_class & F_CLASS_EXTEND)
    329 	    {
    330 	      value = (insn & 0x1F);
    331 	      if (arcExtMap_condCodeName (value))
    332 		continue;
    333 	    }
    334 
    335 	  /* Check for the implicit flags.  */
    336 	  if (cl_flags->flag_class & F_CLASS_IMPLICIT)
    337 	    continue;
    338 
    339 	  for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
    340 	    {
    341 	      const struct arc_flag_operand *flg_operand =
    342 		&arc_flag_operands[*flgopridx];
    343 
    344 	      value = (insn >> flg_operand->shift)
    345 		& ((1 << flg_operand->bits) - 1);
    346 	      if (value == flg_operand->code)
    347 		foundA = 1;
    348 	      if (value)
    349 		foundB = 1;
    350 	    }
    351 
    352 	  if (!foundA && foundB)
    353 	    {
    354 	      invalid = TRUE;
    355 	      break;
    356 	    }
    357 	}
    358 
    359       if (invalid)
    360 	continue;
    361 
    362       if (insn_len == 4
    363 	  && overlaps)
    364 	{
    365 	  warn_p = TRUE;
    366 	  t_op = opcode;
    367 	  if (skip_this_opcode (opcode))
    368 	    continue;
    369 	}
    370 
    371       /* The instruction is valid.  */
    372       return opcode;
    373     }
    374   while (opcode->mask);
    375 
    376   if (warn_p)
    377     {
    378       info->fprintf_func (info->stream,
    379 			  _("\nWarning: disassembly may be wrong due to "
    380 			    "guessed opcode class choice.\n"
    381 			    "Use -M<class[,class]> to select the correct "
    382 			    "opcode class(es).\n\t\t\t\t"));
    383       return t_op;
    384     }
    385 
    386   return NULL;
    387 }
    388 
    389 /* Find opcode for INSN, trying various different sources.  The instruction
    390    length in INSN_LEN will be updated if the instruction requires a LIMM
    391    extension.
    392 
    393    A pointer to the opcode is placed into OPCODE_RESULT, and ITER is
    394    initialised, ready to iterate over the operands of the found opcode.  If
    395    the found opcode requires a LIMM then the LIMM value will be loaded into a
    396    field of ITER.
    397 
    398    This function returns TRUE in almost all cases, FALSE is reserved to
    399    indicate an error (failing to find an opcode is not an error) a returned
    400    result of FALSE would indicate that the disassembler can't continue.
    401 
    402    If no matching opcode is found then the returned result will be TRUE, the
    403    value placed into OPCODE_RESULT will be NULL, ITER will be undefined, and
    404    INSN_LEN will be unchanged.
    405 
    406    If a matching opcode is found, then the returned result will be TRUE, the
    407    opcode pointer is placed into OPCODE_RESULT, INSN_LEN will be increased by
    408    4 if the instruction requires a LIMM, and the LIMM value will have been
    409    loaded into a field of ITER.  Finally, ITER will have been initialised so
    410    that calls to OPERAND_ITERATOR_NEXT will iterate over the opcode's
    411    operands.  */
    412 
    413 static bfd_boolean
    414 find_format (bfd_vma                       memaddr,
    415 	     unsigned long long            insn,
    416 	     unsigned int *                insn_len,
    417              unsigned                      isa_mask,
    418 	     struct disassemble_info *     info,
    419              const struct arc_opcode **    opcode_result,
    420              struct arc_operand_iterator * iter)
    421 {
    422   const struct arc_opcode *opcode = NULL;
    423   bfd_boolean needs_limm = FALSE;
    424   const extInstruction_t *einsn, *i;
    425   unsigned limm = 0;
    426   struct arc_disassemble_info *arc_infop = info->private_data;
    427 
    428   /* First, try the extension instructions.  */
    429   if (*insn_len == 4)
    430     {
    431       einsn = arcExtMap_insn (OPCODE_32BIT_INSN (insn), insn);
    432       for (i = einsn; (i != NULL) && (opcode == NULL); i = i->next)
    433 	{
    434 	  const char *errmsg = NULL;
    435 
    436 	  opcode = arcExtMap_genOpcode (i, isa_mask, &errmsg);
    437 	  if (opcode == NULL)
    438 	    {
    439 	      (*info->fprintf_func) (info->stream,
    440 				     _("An error occurred while generating the "
    441 				       "extension instruction operations"));
    442 	      *opcode_result = NULL;
    443 	      return FALSE;
    444 	    }
    445 
    446 	  opcode = find_format_from_table (info, opcode, insn, *insn_len,
    447 					   isa_mask, &needs_limm, FALSE);
    448 	}
    449     }
    450 
    451   /* Then, try finding the first match in the opcode table.  */
    452   if (opcode == NULL)
    453     opcode = find_format_from_table (info, arc_opcodes, insn, *insn_len,
    454 				     isa_mask, &needs_limm, TRUE);
    455 
    456   if (opcode != NULL && needs_limm)
    457     {
    458       bfd_byte buffer[4];
    459       int status;
    460 
    461       status = (*info->read_memory_func) (memaddr + *insn_len, buffer,
    462                                           4, info);
    463       if (status != 0)
    464         {
    465           opcode = NULL;
    466         }
    467       else
    468         {
    469           limm = ARRANGE_ENDIAN (info, buffer);
    470           *insn_len += 4;
    471         }
    472     }
    473 
    474   if (opcode != NULL)
    475     {
    476       iter->insn = insn;
    477       iter->limm = limm;
    478       iter->opcode = opcode;
    479       iter->opidx = opcode->operands;
    480     }
    481 
    482   *opcode_result = opcode;
    483 
    484   /* Update private data.  */
    485   arc_infop->opcode = opcode;
    486   arc_infop->limm = limm;
    487   arc_infop->limm_p = needs_limm;
    488 
    489   return TRUE;
    490 }
    491 
    492 static void
    493 print_flags (const struct arc_opcode *opcode,
    494 	     unsigned long long *insn,
    495 	     struct disassemble_info *info)
    496 {
    497   const unsigned char *flgidx;
    498   unsigned int value;
    499   struct arc_disassemble_info *arc_infop = info->private_data;
    500 
    501   /* Now extract and print the flags.  */
    502   for (flgidx = opcode->flags; *flgidx; flgidx++)
    503     {
    504       /* Get a valid flag class.  */
    505       const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
    506       const unsigned *flgopridx;
    507 
    508       /* Check first the extensions.  */
    509       if (cl_flags->flag_class & F_CLASS_EXTEND)
    510 	{
    511 	  const char *name;
    512 	  value = (insn[0] & 0x1F);
    513 
    514 	  name = arcExtMap_condCodeName (value);
    515 	  if (name)
    516 	    {
    517 	      (*info->fprintf_func) (info->stream, ".%s", name);
    518 	      continue;
    519 	    }
    520 	}
    521 
    522       for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
    523 	{
    524 	  const struct arc_flag_operand *flg_operand =
    525 	    &arc_flag_operands[*flgopridx];
    526 
    527 	  /* Implicit flags are only used for the insn decoder.  */
    528 	  if (cl_flags->flag_class & F_CLASS_IMPLICIT)
    529 	    {
    530 	      if (cl_flags->flag_class & F_CLASS_COND)
    531 		arc_infop->condition_code = flg_operand->code;
    532 	      else if (cl_flags->flag_class & F_CLASS_WB)
    533 		arc_infop->writeback_mode = flg_operand->code;
    534 	      else if (cl_flags->flag_class & F_CLASS_ZZ)
    535 		info->data_size = flg_operand->code;
    536 	      continue;
    537 	    }
    538 
    539 	  if (!flg_operand->favail)
    540 	    continue;
    541 
    542 	  value = (insn[0] >> flg_operand->shift)
    543 	    & ((1 << flg_operand->bits) - 1);
    544 	  if (value == flg_operand->code)
    545 	    {
    546 	       /* FIXME!: print correctly nt/t flag.  */
    547 	      if (!special_flag_p (opcode->name, flg_operand->name))
    548 		(*info->fprintf_func) (info->stream, ".");
    549 	      else if (info->insn_type == dis_dref)
    550 		{
    551 		  switch (flg_operand->name[0])
    552 		    {
    553 		    case 'b':
    554 		      info->data_size = 1;
    555 		      break;
    556 		    case 'h':
    557 		    case 'w':
    558 		      info->data_size = 2;
    559 		      break;
    560 		    default:
    561 		      info->data_size = 4;
    562 		      break;
    563 		    }
    564 		}
    565 	      if (flg_operand->name[0] == 'd'
    566 		  && flg_operand->name[1] == 0)
    567 		info->branch_delay_insns = 1;
    568 
    569 	      /* Check if it is a conditional flag.  */
    570 	      if (cl_flags->flag_class & F_CLASS_COND)
    571 		{
    572 		  if (info->insn_type == dis_jsr)
    573 		    info->insn_type = dis_condjsr;
    574 		  else if (info->insn_type == dis_branch)
    575 		    info->insn_type = dis_condbranch;
    576 		  arc_infop->condition_code = flg_operand->code;
    577 		}
    578 
    579 	      /* Check for the write back modes.  */
    580 	      if (cl_flags->flag_class & F_CLASS_WB)
    581 		arc_infop->writeback_mode = flg_operand->code;
    582 
    583 	      (*info->fprintf_func) (info->stream, "%s", flg_operand->name);
    584 	    }
    585 	}
    586     }
    587 }
    588 
    589 static const char *
    590 get_auxreg (const struct arc_opcode *opcode,
    591 	    int value,
    592 	    unsigned isa_mask)
    593 {
    594   const char *name;
    595   unsigned int i;
    596   const struct arc_aux_reg *auxr = &arc_aux_regs[0];
    597 
    598   if (opcode->insn_class != AUXREG)
    599     return NULL;
    600 
    601   name = arcExtMap_auxRegName (value);
    602   if (name)
    603     return name;
    604 
    605   for (i = 0; i < arc_num_aux_regs; i++, auxr++)
    606     {
    607       if (!(auxr->cpu & isa_mask))
    608 	continue;
    609 
    610       if (auxr->subclass != NONE)
    611 	return NULL;
    612 
    613       if (auxr->address == value)
    614 	return auxr->name;
    615     }
    616   return NULL;
    617 }
    618 
    619 /* Convert a value representing an address type to a string used to refer to
    620    the address type in assembly code.  */
    621 
    622 static const char *
    623 get_addrtype (int value)
    624 {
    625   if (value < 0 || value > addrtypenames_max)
    626     return addrtypeunknown;
    627 
    628   return addrtypenames[value];
    629 }
    630 
    631 /* Calculate the instruction length for an instruction starting with MSB
    632    and LSB, the most and least significant byte.  The ISA_MASK is used to
    633    filter the instructions considered to only those that are part of the
    634    current architecture.
    635 
    636    The instruction lengths are calculated from the ARC_OPCODE table, and
    637    cached for later use.  */
    638 
    639 static unsigned int
    640 arc_insn_length (bfd_byte msb, bfd_byte lsb, struct disassemble_info *info)
    641 {
    642   bfd_byte major_opcode = msb >> 3;
    643 
    644   switch (info->mach)
    645     {
    646     case bfd_mach_arc_arc700:
    647       /* The nps400 extension set requires this special casing of the
    648 	 instruction length calculation.  Right now this is not causing any
    649 	 problems as none of the known extensions overlap in opcode space,
    650 	 but, if they ever do then we might need to start carrying
    651 	 information around in the elf about which extensions are in use.  */
    652       if (major_opcode == 0xb)
    653         {
    654           bfd_byte minor_opcode = lsb & 0x1f;
    655 
    656 	  if (minor_opcode < 4)
    657 	    return 6;
    658 	  else if (minor_opcode == 0x10 || minor_opcode == 0x11)
    659 	    return 8;
    660         }
    661       if (major_opcode == 0xa)
    662         {
    663           return 8;
    664         }
    665       /* Fall through.  */
    666     case bfd_mach_arc_arc600:
    667       return (major_opcode > 0xb) ? 2 : 4;
    668       break;
    669 
    670     case bfd_mach_arc_arcv2:
    671       return (major_opcode > 0x7) ? 2 : 4;
    672       break;
    673 
    674     default:
    675       return 0;
    676     }
    677 }
    678 
    679 /* Extract and return the value of OPERAND from the instruction whose value
    680    is held in the array INSN.  */
    681 
    682 static int
    683 extract_operand_value (const struct arc_operand *operand,
    684 		       unsigned long long insn,
    685 		       unsigned limm)
    686 {
    687   int value;
    688 
    689   /* Read the limm operand, if required.  */
    690   if (operand->flags & ARC_OPERAND_LIMM)
    691     /* The second part of the instruction value will have been loaded as
    692        part of the find_format call made earlier.  */
    693     value = limm;
    694   else
    695     {
    696       if (operand->extract)
    697         value = (*operand->extract) (insn, (int *) NULL);
    698       else
    699         {
    700           if (operand->flags & ARC_OPERAND_ALIGNED32)
    701             {
    702               value = (insn >> operand->shift)
    703                 & ((1 << (operand->bits - 2)) - 1);
    704               value = value << 2;
    705             }
    706           else
    707             {
    708               value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
    709             }
    710           if (operand->flags & ARC_OPERAND_SIGNED)
    711             {
    712               int signbit = 1 << (operand->bits - 1);
    713               value = (value ^ signbit) - signbit;
    714             }
    715         }
    716     }
    717 
    718   return value;
    719 }
    720 
    721 /* Find the next operand, and the operands value from ITER.  Return TRUE if
    722    there is another operand, otherwise return FALSE.  If there is an
    723    operand returned then the operand is placed into OPERAND, and the value
    724    into VALUE.  If there is no operand returned then OPERAND and VALUE are
    725    unchanged.  */
    726 
    727 static bfd_boolean
    728 operand_iterator_next (struct arc_operand_iterator *iter,
    729                        const struct arc_operand **operand,
    730                        int *value)
    731 {
    732   if (*iter->opidx == 0)
    733     {
    734       *operand = NULL;
    735       return FALSE;
    736     }
    737 
    738   *operand = &arc_operands[*iter->opidx];
    739   *value = extract_operand_value (*operand, iter->insn, iter->limm);
    740   iter->opidx++;
    741 
    742   return TRUE;
    743 }
    744 
    745 /* Helper for parsing the options.  */
    746 
    747 static void
    748 parse_option (const char *option)
    749 {
    750   if (disassembler_options_cmp (option, "dsp") == 0)
    751     add_to_decodelist (DSP, NONE);
    752 
    753   else if (disassembler_options_cmp (option, "spfp") == 0)
    754     add_to_decodelist (FLOAT, SPX);
    755 
    756   else if (disassembler_options_cmp (option, "dpfp") == 0)
    757     add_to_decodelist (FLOAT, DPX);
    758 
    759   else if (disassembler_options_cmp (option, "quarkse_em") == 0)
    760     {
    761       add_to_decodelist (FLOAT, DPX);
    762       add_to_decodelist (FLOAT, SPX);
    763       add_to_decodelist (FLOAT, QUARKSE1);
    764       add_to_decodelist (FLOAT, QUARKSE2);
    765     }
    766 
    767   else if (disassembler_options_cmp (option, "fpuda") == 0)
    768     add_to_decodelist (FLOAT, DPA);
    769 
    770   else if (disassembler_options_cmp (option, "nps400") == 0)
    771     {
    772       add_to_decodelist (ACL, NPS400);
    773       add_to_decodelist (ARITH, NPS400);
    774       add_to_decodelist (BITOP, NPS400);
    775       add_to_decodelist (BMU, NPS400);
    776       add_to_decodelist (CONTROL, NPS400);
    777       add_to_decodelist (DMA, NPS400);
    778       add_to_decodelist (DPI, NPS400);
    779       add_to_decodelist (MEMORY, NPS400);
    780       add_to_decodelist (MISC, NPS400);
    781       add_to_decodelist (NET, NPS400);
    782       add_to_decodelist (PMU, NPS400);
    783       add_to_decodelist (PROTOCOL_DECODE, NPS400);
    784       add_to_decodelist (ULTRAIP, NPS400);
    785     }
    786 
    787   else if (disassembler_options_cmp (option, "fpus") == 0)
    788     {
    789       add_to_decodelist (FLOAT, SP);
    790       add_to_decodelist (FLOAT, CVT);
    791     }
    792 
    793   else if (disassembler_options_cmp (option, "fpud") == 0)
    794     {
    795       add_to_decodelist (FLOAT, DP);
    796       add_to_decodelist (FLOAT, CVT);
    797     }
    798   else if (CONST_STRNEQ (option, "hex"))
    799     print_hex = TRUE;
    800   else
    801     /* xgettext:c-format */
    802     opcodes_error_handler (_("unrecognised disassembler option: %s"), option);
    803 }
    804 
    805 #define ARC_CPU_TYPE_A6xx(NAME,EXTRA)			\
    806   { #NAME, ARC_OPCODE_ARC600, "ARC600" }
    807 #define ARC_CPU_TYPE_A7xx(NAME,EXTRA)			\
    808   { #NAME, ARC_OPCODE_ARC700, "ARC700" }
    809 #define ARC_CPU_TYPE_AV2EM(NAME,EXTRA)			\
    810   { #NAME,  ARC_OPCODE_ARCv2EM, "ARC EM" }
    811 #define ARC_CPU_TYPE_AV2HS(NAME,EXTRA)			\
    812   { #NAME,  ARC_OPCODE_ARCv2HS, "ARC HS" }
    813 #define ARC_CPU_TYPE_NONE				\
    814   { 0, 0, 0 }
    815 
    816 /* A table of CPU names and opcode sets.  */
    817 static const struct cpu_type
    818 {
    819   const char *name;
    820   unsigned flags;
    821   const char *isa;
    822 }
    823   cpu_types[] =
    824 {
    825   #include "elf/arc-cpu.def"
    826 };
    827 
    828 /* Helper for parsing the CPU options.  Accept any of the ARC architectures
    829    values.  OPTION should be a value passed to cpu=.  */
    830 
    831 static unsigned
    832 parse_cpu_option (const char *option)
    833 {
    834   int i;
    835 
    836   for (i = 0; cpu_types[i].name; ++i)
    837     {
    838       if (!disassembler_options_cmp (cpu_types[i].name, option))
    839 	{
    840 	  return cpu_types[i].flags;
    841 	}
    842     }
    843 
    844   /* xgettext:c-format */
    845   opcodes_error_handler (_("unrecognised disassembler CPU option: %s"), option);
    846   return ARC_OPCODE_NONE;
    847 }
    848 
    849 /* Go over the options list and parse it.  */
    850 
    851 static void
    852 parse_disassembler_options (const char *options)
    853 {
    854   const char *option;
    855 
    856   if (options == NULL)
    857     return;
    858 
    859   /* Disassembler might be reused for difference CPU's, and cpu option set for
    860      the first one shouldn't be applied to second (which might not have
    861      explicit cpu in its options.  Therefore it is required to reset enforced
    862      CPU when new options are being parsed.  */
    863   enforced_isa_mask = ARC_OPCODE_NONE;
    864 
    865   FOR_EACH_DISASSEMBLER_OPTION (option, options)
    866     {
    867       /* A CPU option?  Cannot use STRING_COMMA_LEN because strncmp is also a
    868 	 preprocessor macro.  */
    869       if (strncmp (option, "cpu=", 4) == 0)
    870 	/* Strip leading `cpu=`.  */
    871 	enforced_isa_mask = parse_cpu_option (option + 4);
    872       else
    873 	parse_option (option);
    874     }
    875 }
    876 
    877 /* Return the instruction type for an instruction described by OPCODE.  */
    878 
    879 static enum dis_insn_type
    880 arc_opcode_to_insn_type (const struct arc_opcode *opcode)
    881 {
    882   enum dis_insn_type insn_type;
    883 
    884   switch (opcode->insn_class)
    885     {
    886     case BRANCH:
    887     case BBIT0:
    888     case BBIT1:
    889     case BI:
    890     case BIH:
    891     case BRCC:
    892     case EI:
    893     case JLI:
    894     case JUMP:
    895     case LOOP:
    896       if (!strncmp (opcode->name, "bl", 2)
    897 	  || !strncmp (opcode->name, "jl", 2))
    898 	{
    899 	  if (opcode->subclass == COND)
    900 	    insn_type = dis_condjsr;
    901 	  else
    902 	    insn_type = dis_jsr;
    903 	}
    904       else
    905 	{
    906 	  if (opcode->subclass == COND)
    907 	    insn_type = dis_condbranch;
    908 	  else
    909 	    insn_type = dis_branch;
    910 	}
    911       break;
    912     case LOAD:
    913     case STORE:
    914     case MEMORY:
    915     case ENTER:
    916     case PUSH:
    917     case POP:
    918       insn_type = dis_dref;
    919       break;
    920     case LEAVE:
    921       insn_type = dis_branch;
    922       break;
    923     default:
    924       insn_type = dis_nonbranch;
    925       break;
    926     }
    927 
    928   return insn_type;
    929 }
    930 
    931 /* Disassemble ARC instructions.  */
    932 
    933 static int
    934 print_insn_arc (bfd_vma memaddr,
    935 		struct disassemble_info *info)
    936 {
    937   bfd_byte buffer[8];
    938   unsigned int highbyte, lowbyte;
    939   int status;
    940   unsigned int insn_len;
    941   unsigned long long insn = 0;
    942   unsigned isa_mask = ARC_OPCODE_NONE;
    943   const struct arc_opcode *opcode;
    944   bfd_boolean need_comma;
    945   bfd_boolean open_braket;
    946   int size;
    947   const struct arc_operand *operand;
    948   int value, vpcl;
    949   struct arc_operand_iterator iter;
    950   struct arc_disassemble_info *arc_infop;
    951   bfd_boolean rpcl = FALSE, rset = FALSE;
    952 
    953   if (info->disassembler_options)
    954     {
    955       parse_disassembler_options (info->disassembler_options);
    956 
    957       /* Avoid repeated parsing of the options.  */
    958       info->disassembler_options = NULL;
    959     }
    960 
    961   if (info->private_data == NULL && !init_arc_disasm_info (info))
    962     return -1;
    963 
    964   memset (&iter, 0, sizeof (iter));
    965   highbyte  = ((info->endian == BFD_ENDIAN_LITTLE) ? 1 : 0);
    966   lowbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 0 : 1);
    967 
    968   /* Figure out CPU type, unless it was enforced via disassembler options.  */
    969   if (enforced_isa_mask == ARC_OPCODE_NONE)
    970     {
    971       Elf_Internal_Ehdr *header = NULL;
    972 
    973       if (info->section && info->section->owner)
    974 	header = elf_elfheader (info->section->owner);
    975 
    976       switch (info->mach)
    977 	{
    978 	case bfd_mach_arc_arc700:
    979 	  isa_mask = ARC_OPCODE_ARC700;
    980 	  break;
    981 
    982 	case bfd_mach_arc_arc600:
    983 	  isa_mask = ARC_OPCODE_ARC600;
    984 	  break;
    985 
    986 	case bfd_mach_arc_arcv2:
    987 	default:
    988 	  isa_mask = ARC_OPCODE_ARCv2EM;
    989 	  /* TODO: Perhaps remove definition of header since it is only used at
    990 	     this location.  */
    991 	  if (header != NULL
    992 	      && (header->e_flags & EF_ARC_MACH_MSK) == EF_ARC_CPU_ARCV2HS)
    993 	    isa_mask = ARC_OPCODE_ARCv2HS;
    994 	  break;
    995 	}
    996     }
    997   else
    998     isa_mask = enforced_isa_mask;
    999 
   1000   if (isa_mask == ARC_OPCODE_ARCv2HS)
   1001     {
   1002       /* FPU instructions are not extensions for HS.  */
   1003       add_to_decodelist (FLOAT, SP);
   1004       add_to_decodelist (FLOAT, DP);
   1005       add_to_decodelist (FLOAT, CVT);
   1006     }
   1007 
   1008   /* This variable may be set by the instruction decoder.  It suggests
   1009      the number of bytes objdump should display on a single line.  If
   1010      the instruction decoder sets this, it should always set it to
   1011      the same value in order to get reasonable looking output.  */
   1012   info->bytes_per_line  = 8;
   1013 
   1014   /* In the next lines, we set two info variables control the way
   1015      objdump displays the raw data.  For example, if bytes_per_line is
   1016      8 and bytes_per_chunk is 4, the output will look like this:
   1017      00:   00000000 00000000
   1018      with the chunks displayed according to "display_endian".  */
   1019   if (info->section
   1020       && !(info->section->flags & SEC_CODE))
   1021     {
   1022       /* This is not a CODE section.  */
   1023       switch (info->section->size)
   1024 	{
   1025 	case 1:
   1026 	case 2:
   1027 	case 4:
   1028 	  size = info->section->size;
   1029 	  break;
   1030 	default:
   1031 	  size = (info->section->size & 0x01) ? 1 : 4;
   1032 	  break;
   1033 	}
   1034       info->bytes_per_chunk = 1;
   1035       info->display_endian = info->endian;
   1036     }
   1037   else
   1038     {
   1039       size = 2;
   1040       info->bytes_per_chunk = 2;
   1041       info->display_endian = info->endian;
   1042     }
   1043 
   1044   /* Read the insn into a host word.  */
   1045   status = (*info->read_memory_func) (memaddr, buffer, size, info);
   1046 
   1047   if (status != 0)
   1048     {
   1049       (*info->memory_error_func) (status, memaddr, info);
   1050       return -1;
   1051     }
   1052 
   1053   if (info->section
   1054       && !(info->section->flags & SEC_CODE))
   1055     {
   1056       /* Data section.  */
   1057       unsigned long data;
   1058 
   1059       data = bfd_get_bits (buffer, size * 8,
   1060 			   info->display_endian == BFD_ENDIAN_BIG);
   1061       switch (size)
   1062 	{
   1063 	case 1:
   1064 	  (*info->fprintf_func) (info->stream, ".byte\t0x%02lx", data);
   1065 	  break;
   1066 	case 2:
   1067 	  (*info->fprintf_func) (info->stream, ".short\t0x%04lx", data);
   1068 	  break;
   1069 	case 4:
   1070 	  (*info->fprintf_func) (info->stream, ".word\t0x%08lx", data);
   1071 	  break;
   1072 	default:
   1073 	  return -1;
   1074 	}
   1075       return size;
   1076     }
   1077 
   1078   insn_len = arc_insn_length (buffer[highbyte], buffer[lowbyte], info);
   1079   pr_debug ("instruction length = %d bytes\n", insn_len);
   1080   if (insn_len == 0)
   1081     return -1;
   1082 
   1083   arc_infop = info->private_data;
   1084   arc_infop->insn_len = insn_len;
   1085 
   1086   switch (insn_len)
   1087     {
   1088     case 2:
   1089       insn = (buffer[highbyte] << 8) | buffer[lowbyte];
   1090       break;
   1091 
   1092     case 4:
   1093       {
   1094 	/* This is a long instruction: Read the remaning 2 bytes.  */
   1095 	status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 2, info);
   1096 	if (status != 0)
   1097 	  {
   1098 	    (*info->memory_error_func) (status, memaddr + 2, info);
   1099 	    return -1;
   1100 	  }
   1101 	insn = (unsigned long long) ARRANGE_ENDIAN (info, buffer);
   1102       }
   1103       break;
   1104 
   1105     case 6:
   1106       {
   1107 	status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 4, info);
   1108 	if (status != 0)
   1109 	  {
   1110 	    (*info->memory_error_func) (status, memaddr + 2, info);
   1111 	    return -1;
   1112 	  }
   1113 	insn = (unsigned long long) ARRANGE_ENDIAN (info, &buffer[2]);
   1114 	insn |= ((unsigned long long) buffer[highbyte] << 40)
   1115 	  | ((unsigned long long) buffer[lowbyte] << 32);
   1116       }
   1117       break;
   1118 
   1119     case 8:
   1120       {
   1121 	status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 6, info);
   1122 	if (status != 0)
   1123 	  {
   1124 	    (*info->memory_error_func) (status, memaddr + 2, info);
   1125 	    return -1;
   1126 	  }
   1127 	insn =
   1128 	  ((((unsigned long long) ARRANGE_ENDIAN (info, buffer)) << 32)
   1129 	   | ((unsigned long long) ARRANGE_ENDIAN (info, &buffer[4])));
   1130       }
   1131       break;
   1132 
   1133     default:
   1134       /* There is no instruction whose length is not 2, 4, 6, or 8.  */
   1135       return -1;
   1136     }
   1137 
   1138   pr_debug ("instruction value = %llx\n", insn);
   1139 
   1140   /* Set some defaults for the insn info.  */
   1141   info->insn_info_valid    = 1;
   1142   info->branch_delay_insns = 0;
   1143   info->data_size	   = 4;
   1144   info->insn_type	   = dis_nonbranch;
   1145   info->target		   = 0;
   1146   info->target2		   = 0;
   1147 
   1148   /* FIXME to be moved in dissasemble_init_for_target.  */
   1149   info->disassembler_needs_relocs = TRUE;
   1150 
   1151   /* Find the first match in the opcode table.  */
   1152   if (!find_format (memaddr, insn, &insn_len, isa_mask, info, &opcode, &iter))
   1153     return -1;
   1154 
   1155   if (!opcode)
   1156     {
   1157       switch (insn_len)
   1158 	{
   1159 	case 2:
   1160 	  (*info->fprintf_func) (info->stream, ".shor\t%#04llx",
   1161 				 insn & 0xffff);
   1162 	  break;
   1163 
   1164 	case 4:
   1165 	  (*info->fprintf_func) (info->stream, ".word\t%#08llx",
   1166 				 insn & 0xffffffff);
   1167 	  break;
   1168 
   1169 	case 6:
   1170 	  (*info->fprintf_func) (info->stream, ".long\t%#08llx",
   1171 				 insn & 0xffffffff);
   1172 	  (*info->fprintf_func) (info->stream, ".long\t%#04llx",
   1173 				 (insn >> 32) & 0xffff);
   1174 	  break;
   1175 
   1176 	case 8:
   1177 	  (*info->fprintf_func) (info->stream, ".long\t%#08llx",
   1178 				 insn & 0xffffffff);
   1179 	  (*info->fprintf_func) (info->stream, ".long\t%#08llx",
   1180 				 insn >> 32);
   1181 	  break;
   1182 
   1183 	default:
   1184 	  return -1;
   1185 	}
   1186 
   1187       info->insn_type = dis_noninsn;
   1188       return insn_len;
   1189     }
   1190 
   1191   /* Print the mnemonic.  */
   1192   (*info->fprintf_func) (info->stream, "%s", opcode->name);
   1193 
   1194   /* Preselect the insn class.  */
   1195   info->insn_type = arc_opcode_to_insn_type (opcode);
   1196 
   1197   pr_debug ("%s: 0x%08llx\n", opcode->name, opcode->opcode);
   1198 
   1199   print_flags (opcode, &insn, info);
   1200 
   1201   if (opcode->operands[0] != 0)
   1202     (*info->fprintf_func) (info->stream, "\t");
   1203 
   1204   need_comma = FALSE;
   1205   open_braket = FALSE;
   1206   arc_infop->operands_count = 0;
   1207 
   1208   /* Now extract and print the operands.  */
   1209   operand = NULL;
   1210   vpcl = 0;
   1211   while (operand_iterator_next (&iter, &operand, &value))
   1212     {
   1213       if (open_braket && (operand->flags & ARC_OPERAND_BRAKET))
   1214 	{
   1215 	  (*info->fprintf_func) (info->stream, "]");
   1216 	  open_braket = FALSE;
   1217 	  continue;
   1218 	}
   1219 
   1220       /* Only take input from real operands.  */
   1221       if (ARC_OPERAND_IS_FAKE (operand))
   1222 	continue;
   1223 
   1224       if ((operand->flags & ARC_OPERAND_IGNORE)
   1225 	  && (operand->flags & ARC_OPERAND_IR)
   1226 	  && value == -1)
   1227 	continue;
   1228 
   1229       if (operand->flags & ARC_OPERAND_COLON)
   1230 	{
   1231 	  (*info->fprintf_func) (info->stream, ":");
   1232 	  continue;
   1233 	}
   1234 
   1235       if (need_comma)
   1236 	(*info->fprintf_func) (info->stream, ",");
   1237 
   1238       if (!open_braket && (operand->flags & ARC_OPERAND_BRAKET))
   1239 	{
   1240 	  (*info->fprintf_func) (info->stream, "[");
   1241 	  open_braket = TRUE;
   1242 	  need_comma = FALSE;
   1243 	  continue;
   1244 	}
   1245 
   1246       need_comma = TRUE;
   1247 
   1248       if (operand->flags & ARC_OPERAND_PCREL)
   1249 	{
   1250 	  rpcl = TRUE;
   1251 	  vpcl = value;
   1252 	  rset = TRUE;
   1253 
   1254 	  info->target = (bfd_vma) (memaddr & ~3) + value;
   1255 	}
   1256       else if (!(operand->flags & ARC_OPERAND_IR))
   1257 	{
   1258 	  vpcl = value;
   1259 	  rset = TRUE;
   1260 	}
   1261 
   1262       /* Print the operand as directed by the flags.  */
   1263       if (operand->flags & ARC_OPERAND_IR)
   1264 	{
   1265 	  const char *rname;
   1266 
   1267 	  assert (value >=0 && value < 64);
   1268 	  rname = arcExtMap_coreRegName (value);
   1269 	  if (!rname)
   1270 	    rname = regnames[value];
   1271 	  (*info->fprintf_func) (info->stream, "%s", rname);
   1272 
   1273 	  /* Check if we have a double register to print.  */
   1274 	  if (operand->flags & ARC_OPERAND_TRUNCATE)
   1275 	    {
   1276 	      if ((value & 0x01) == 0)
   1277 		{
   1278 		  rname = arcExtMap_coreRegName (value + 1);
   1279 		  if (!rname)
   1280 		    rname = regnames[value + 1];
   1281 		}
   1282 	      else
   1283 		rname = _("\nWarning: illegal use of double register "
   1284 			  "pair.\n");
   1285 	      (*info->fprintf_func) (info->stream, "%s", rname);
   1286 	    }
   1287 	  if (value == 63)
   1288 	    rpcl = TRUE;
   1289 	  else
   1290 	    rpcl = FALSE;
   1291 	}
   1292       else if (operand->flags & ARC_OPERAND_LIMM)
   1293 	{
   1294 	  const char *rname = get_auxreg (opcode, value, isa_mask);
   1295 
   1296 	  if (rname && open_braket)
   1297 	    (*info->fprintf_func) (info->stream, "%s", rname);
   1298 	  else
   1299 	    {
   1300 	      (*info->fprintf_func) (info->stream, "%#x", value);
   1301 	      if (info->insn_type == dis_branch
   1302 		  || info->insn_type == dis_jsr)
   1303 		info->target = (bfd_vma) value;
   1304 	    }
   1305 	}
   1306       else if (operand->flags & ARC_OPERAND_SIGNED)
   1307 	{
   1308 	  const char *rname = get_auxreg (opcode, value, isa_mask);
   1309 	  if (rname && open_braket)
   1310 	    (*info->fprintf_func) (info->stream, "%s", rname);
   1311 	  else
   1312 	    {
   1313 	      if (print_hex)
   1314 		(*info->fprintf_func) (info->stream, "%#x", value);
   1315 	      else
   1316 		(*info->fprintf_func) (info->stream, "%d", value);
   1317 	    }
   1318 	}
   1319       else if (operand->flags & ARC_OPERAND_ADDRTYPE)
   1320 	{
   1321 	  const char *addrtype = get_addrtype (value);
   1322 	  (*info->fprintf_func) (info->stream, "%s", addrtype);
   1323 	  /* A colon follow an address type.  */
   1324 	  need_comma = FALSE;
   1325 	}
   1326       else
   1327 	{
   1328 	  if (operand->flags & ARC_OPERAND_TRUNCATE
   1329 	      && !(operand->flags & ARC_OPERAND_ALIGNED32)
   1330 	      && !(operand->flags & ARC_OPERAND_ALIGNED16)
   1331 	      && value >= 0 && value <= 14)
   1332 	    {
   1333 	      /* Leave/Enter mnemonics.  */
   1334 	      switch (value)
   1335 		{
   1336 		case 0:
   1337 		  need_comma = FALSE;
   1338 		  break;
   1339 		case 1:
   1340 		  (*info->fprintf_func) (info->stream, "r13");
   1341 		  break;
   1342 		default:
   1343 		  (*info->fprintf_func) (info->stream, "r13-%s",
   1344 					 regnames[13 + value - 1]);
   1345 		  break;
   1346 		}
   1347 	      rpcl = FALSE;
   1348 	      rset = FALSE;
   1349 	    }
   1350 	  else
   1351 	    {
   1352 	      const char *rname = get_auxreg (opcode, value, isa_mask);
   1353 	      if (rname && open_braket)
   1354 		(*info->fprintf_func) (info->stream, "%s", rname);
   1355 	      else
   1356 		(*info->fprintf_func) (info->stream, "%#x", value);
   1357 	    }
   1358 	}
   1359 
   1360       if (operand->flags & ARC_OPERAND_LIMM)
   1361 	{
   1362 	  arc_infop->operands[arc_infop->operands_count].kind
   1363 	    = ARC_OPERAND_KIND_LIMM;
   1364 	  /* It is not important to have exactly the LIMM indicator
   1365 	     here.  */
   1366 	  arc_infop->operands[arc_infop->operands_count].value = 63;
   1367 	}
   1368       else
   1369 	{
   1370 	  arc_infop->operands[arc_infop->operands_count].value = value;
   1371 	  arc_infop->operands[arc_infop->operands_count].kind
   1372 	    = (operand->flags & ARC_OPERAND_IR
   1373 	       ? ARC_OPERAND_KIND_REG
   1374 	       : ARC_OPERAND_KIND_SHIMM);
   1375 	}
   1376       arc_infop->operands_count ++;
   1377     }
   1378 
   1379   /* Pretty print extra info for pc-relative operands.  */
   1380   if (rpcl && rset)
   1381     {
   1382       if (info->flags & INSN_HAS_RELOC)
   1383 	/* If the instruction has a reloc associated with it, then the
   1384 	   offset field in the instruction will actually be the addend
   1385 	   for the reloc.  (We are using REL type relocs).  In such
   1386 	   cases, we can ignore the pc when computing addresses, since
   1387 	   the addend is not currently pc-relative.  */
   1388 	memaddr = 0;
   1389 
   1390       (*info->fprintf_func) (info->stream, "\t;");
   1391       (*info->print_address_func) ((memaddr & ~3) + vpcl, info);
   1392     }
   1393 
   1394   return insn_len;
   1395 }
   1396 
   1397 
   1398 disassembler_ftype
   1399 arc_get_disassembler (bfd *abfd)
   1400 {
   1401   /* BFD my be absent, if opcodes is invoked from the debugger that
   1402      has connected to remote target and doesn't have an ELF file.  */
   1403   if (abfd != NULL)
   1404     {
   1405       /* Read the extension insns and registers, if any.  */
   1406       build_ARC_extmap (abfd);
   1407 #ifdef DEBUG
   1408       dump_ARC_extmap ();
   1409 #endif
   1410     }
   1411 
   1412   return print_insn_arc;
   1413 }
   1414 
   1415 void
   1416 print_arc_disassembler_options (FILE *stream)
   1417 {
   1418   int i;
   1419 
   1420   fprintf (stream, _("\n\
   1421 The following ARC specific disassembler options are supported for use \n\
   1422 with -M switch (multiple options should be separated by commas):\n"));
   1423 
   1424   /* cpu=... options.  */
   1425   for (i = 0; cpu_types[i].name; ++i)
   1426     {
   1427       /* As of now all value CPU values are less than 16 characters.  */
   1428       fprintf (stream, "  cpu=%-16s\tEnforce %s ISA.\n",
   1429 	       cpu_types[i].name, cpu_types[i].isa);
   1430     }
   1431 
   1432   fprintf (stream, _("\
   1433   dsp             Recognize DSP instructions.\n"));
   1434   fprintf (stream, _("\
   1435   spfp            Recognize FPX SP instructions.\n"));
   1436   fprintf (stream, _("\
   1437   dpfp            Recognize FPX DP instructions.\n"));
   1438   fprintf (stream, _("\
   1439   quarkse_em      Recognize FPU QuarkSE-EM instructions.\n"));
   1440   fprintf (stream, _("\
   1441   fpuda           Recognize double assist FPU instructions.\n"));
   1442   fprintf (stream, _("\
   1443   fpus            Recognize single precision FPU instructions.\n"));
   1444   fprintf (stream, _("\
   1445   fpud            Recognize double precision FPU instructions.\n"));
   1446   fprintf (stream, _("\
   1447   nps400          Recognize NPS400 instructions.\n"));
   1448   fprintf (stream, _("\
   1449   hex             Use only hexadecimal number to print immediates.\n"));
   1450 }
   1451 
   1452 void arc_insn_decode (bfd_vma addr,
   1453 		      struct disassemble_info *info,
   1454 		      disassembler_ftype disasm_func,
   1455 		      struct arc_instruction *insn)
   1456 {
   1457   const struct arc_opcode *opcode;
   1458   struct arc_disassemble_info *arc_infop;
   1459 
   1460   /* Ensure that insn would be in the reset state.  */
   1461   memset (insn, 0, sizeof (struct arc_instruction));
   1462 
   1463   /* There was an error when disassembling, for example memory read error.  */
   1464   if (disasm_func (addr, info) < 0)
   1465     {
   1466       insn->valid = FALSE;
   1467       return;
   1468     }
   1469 
   1470   assert (info->private_data != NULL);
   1471   arc_infop = info->private_data;
   1472 
   1473   insn->length  = arc_infop->insn_len;;
   1474   insn->address = addr;
   1475 
   1476   /* Quick exit if memory at this address is not an instruction.  */
   1477   if (info->insn_type == dis_noninsn)
   1478     {
   1479       insn->valid = FALSE;
   1480       return;
   1481     }
   1482 
   1483   insn->valid = TRUE;
   1484 
   1485   opcode = (const struct arc_opcode *) arc_infop->opcode;
   1486   insn->insn_class = opcode->insn_class;
   1487   insn->limm_value = arc_infop->limm;
   1488   insn->limm_p     = arc_infop->limm_p;
   1489 
   1490   insn->is_control_flow = (info->insn_type == dis_branch
   1491 			   || info->insn_type == dis_condbranch
   1492 			   || info->insn_type == dis_jsr
   1493 			   || info->insn_type == dis_condjsr);
   1494 
   1495   insn->has_delay_slot = info->branch_delay_insns;
   1496   insn->writeback_mode
   1497     = (enum arc_ldst_writeback_mode) arc_infop->writeback_mode;
   1498   insn->data_size_mode = info->data_size;
   1499   insn->condition_code = arc_infop->condition_code;
   1500   memcpy (insn->operands, arc_infop->operands,
   1501 	  sizeof (struct arc_insn_operand) * MAX_INSN_ARGS);
   1502   insn->operands_count = arc_infop->operands_count;
   1503 }
   1504 
   1505 /* Local variables:
   1506    eval: (c-set-style "gnu")
   1507    indent-tabs-mode: t
   1508    End:  */
   1509