xref: /netbsd-src/external/gpl3/binutils/dist/opcodes/arc-dis.c (revision 181254a7b1bdde6873432bffef2d2decc4b5c22f)
1 /* Instruction printing code for the ARC.
2    Copyright (C) 1994-2020 Free Software Foundation, Inc.
3 
4    Contributed by Claudiu Zissulescu (claziss@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;
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 occured while generating the extension instruction operations");
441 	      *opcode_result = NULL;
442 	      return FALSE;
443 	    }
444 
445 	  opcode = find_format_from_table (info, opcode, insn, *insn_len,
446 					   isa_mask, &needs_limm, FALSE);
447 	}
448     }
449 
450   /* Then, try finding the first match in the opcode table.  */
451   if (opcode == NULL)
452     opcode = find_format_from_table (info, arc_opcodes, insn, *insn_len,
453 				     isa_mask, &needs_limm, TRUE);
454 
455   if (needs_limm && opcode != NULL)
456     {
457       bfd_byte buffer[4];
458       int status;
459 
460       status = (*info->read_memory_func) (memaddr + *insn_len, buffer,
461                                           4, info);
462       if (status != 0)
463         {
464           opcode = NULL;
465         }
466       else
467         {
468           limm = ARRANGE_ENDIAN (info, buffer);
469           *insn_len += 4;
470         }
471     }
472 
473   if (opcode != NULL)
474     {
475       iter->insn = insn;
476       iter->limm = limm;
477       iter->opcode = opcode;
478       iter->opidx = opcode->operands;
479     }
480 
481   *opcode_result = opcode;
482 
483   /* Update private data.  */
484   arc_infop->opcode = opcode;
485   arc_infop->limm = (needs_limm) ? limm : 0;
486   arc_infop->limm_p = needs_limm;
487 
488   return TRUE;
489 }
490 
491 static void
492 print_flags (const struct arc_opcode *opcode,
493 	     unsigned long long *insn,
494 	     struct disassemble_info *info)
495 {
496   const unsigned char *flgidx;
497   unsigned int value;
498   struct arc_disassemble_info *arc_infop = info->private_data;
499 
500   /* Now extract and print the flags.  */
501   for (flgidx = opcode->flags; *flgidx; flgidx++)
502     {
503       /* Get a valid flag class.  */
504       const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
505       const unsigned *flgopridx;
506 
507       /* Check first the extensions.  */
508       if (cl_flags->flag_class & F_CLASS_EXTEND)
509 	{
510 	  const char *name;
511 	  value = (insn[0] & 0x1F);
512 
513 	  name = arcExtMap_condCodeName (value);
514 	  if (name)
515 	    {
516 	      (*info->fprintf_func) (info->stream, ".%s", name);
517 	      continue;
518 	    }
519 	}
520 
521       for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
522 	{
523 	  const struct arc_flag_operand *flg_operand =
524 	    &arc_flag_operands[*flgopridx];
525 
526 	  /* Implicit flags are only used for the insn decoder.  */
527 	  if (cl_flags->flag_class & F_CLASS_IMPLICIT)
528 	    {
529 	      if (cl_flags->flag_class & F_CLASS_COND)
530 		arc_infop->condition_code = flg_operand->code;
531 	      else if (cl_flags->flag_class & F_CLASS_WB)
532 		arc_infop->writeback_mode = flg_operand->code;
533 	      else if (cl_flags->flag_class & F_CLASS_ZZ)
534 		info->data_size = flg_operand->code;
535 	      continue;
536 	    }
537 
538 	  if (!flg_operand->favail)
539 	    continue;
540 
541 	  value = (insn[0] >> flg_operand->shift)
542 	    & ((1 << flg_operand->bits) - 1);
543 	  if (value == flg_operand->code)
544 	    {
545 	       /* FIXME!: print correctly nt/t flag.  */
546 	      if (!special_flag_p (opcode->name, flg_operand->name))
547 		(*info->fprintf_func) (info->stream, ".");
548 	      else if (info->insn_type == dis_dref)
549 		{
550 		  switch (flg_operand->name[0])
551 		    {
552 		    case 'b':
553 		      info->data_size = 1;
554 		      break;
555 		    case 'h':
556 		    case 'w':
557 		      info->data_size = 2;
558 		      break;
559 		    default:
560 		      info->data_size = 4;
561 		      break;
562 		    }
563 		}
564 	      if (flg_operand->name[0] == 'd'
565 		  && flg_operand->name[1] == 0)
566 		info->branch_delay_insns = 1;
567 
568 	      /* Check if it is a conditional flag.  */
569 	      if (cl_flags->flag_class & F_CLASS_COND)
570 		{
571 		  if (info->insn_type == dis_jsr)
572 		    info->insn_type = dis_condjsr;
573 		  else if (info->insn_type == dis_branch)
574 		    info->insn_type = dis_condbranch;
575 		  arc_infop->condition_code = flg_operand->code;
576 		}
577 
578 	      /* Check for the write back modes.  */
579 	      if (cl_flags->flag_class & F_CLASS_WB)
580 		arc_infop->writeback_mode = flg_operand->code;
581 
582 	      (*info->fprintf_func) (info->stream, "%s", flg_operand->name);
583 	    }
584 	}
585     }
586 }
587 
588 static const char *
589 get_auxreg (const struct arc_opcode *opcode,
590 	    int value,
591 	    unsigned isa_mask)
592 {
593   const char *name;
594   unsigned int i;
595   const struct arc_aux_reg *auxr = &arc_aux_regs[0];
596 
597   if (opcode->insn_class != AUXREG)
598     return NULL;
599 
600   name = arcExtMap_auxRegName (value);
601   if (name)
602     return name;
603 
604   for (i = 0; i < arc_num_aux_regs; i++, auxr++)
605     {
606       if (!(auxr->cpu & isa_mask))
607 	continue;
608 
609       if (auxr->subclass != NONE)
610 	return NULL;
611 
612       if (auxr->address == value)
613 	return auxr->name;
614     }
615   return NULL;
616 }
617 
618 /* Convert a value representing an address type to a string used to refer to
619    the address type in assembly code.  */
620 
621 static const char *
622 get_addrtype (int value)
623 {
624   if (value < 0 || value > addrtypenames_max)
625     return addrtypeunknown;
626 
627   return addrtypenames[value];
628 }
629 
630 /* Calculate the instruction length for an instruction starting with MSB
631    and LSB, the most and least significant byte.  The ISA_MASK is used to
632    filter the instructions considered to only those that are part of the
633    current architecture.
634 
635    The instruction lengths are calculated from the ARC_OPCODE table, and
636    cached for later use.  */
637 
638 static unsigned int
639 arc_insn_length (bfd_byte msb, bfd_byte lsb, struct disassemble_info *info)
640 {
641   bfd_byte major_opcode = msb >> 3;
642 
643   switch (info->mach)
644     {
645     case bfd_mach_arc_arc700:
646       /* The nps400 extension set requires this special casing of the
647 	 instruction length calculation.  Right now this is not causing any
648 	 problems as none of the known extensions overlap in opcode space,
649 	 but, if they ever do then we might need to start carrying
650 	 information around in the elf about which extensions are in use.  */
651       if (major_opcode == 0xb)
652         {
653           bfd_byte minor_opcode = lsb & 0x1f;
654 
655 	  if (minor_opcode < 4)
656 	    return 6;
657 	  else if (minor_opcode == 0x10 || minor_opcode == 0x11)
658 	    return 8;
659         }
660       if (major_opcode == 0xa)
661         {
662           return 8;
663         }
664       /* Fall through.  */
665     case bfd_mach_arc_arc600:
666       return (major_opcode > 0xb) ? 2 : 4;
667       break;
668 
669     case bfd_mach_arc_arcv2:
670       return (major_opcode > 0x7) ? 2 : 4;
671       break;
672 
673     default:
674       return 0;
675     }
676 }
677 
678 /* Extract and return the value of OPERAND from the instruction whose value
679    is held in the array INSN.  */
680 
681 static int
682 extract_operand_value (const struct arc_operand *operand,
683 		       unsigned long long insn,
684 		       unsigned limm)
685 {
686   int value;
687 
688   /* Read the limm operand, if required.  */
689   if (operand->flags & ARC_OPERAND_LIMM)
690     /* The second part of the instruction value will have been loaded as
691        part of the find_format call made earlier.  */
692     value = limm;
693   else
694     {
695       if (operand->extract)
696         value = (*operand->extract) (insn, (int *) NULL);
697       else
698         {
699           if (operand->flags & ARC_OPERAND_ALIGNED32)
700             {
701               value = (insn >> operand->shift)
702                 & ((1 << (operand->bits - 2)) - 1);
703               value = value << 2;
704             }
705           else
706             {
707               value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
708             }
709           if (operand->flags & ARC_OPERAND_SIGNED)
710             {
711               int signbit = 1 << (operand->bits - 1);
712               value = (value ^ signbit) - signbit;
713             }
714         }
715     }
716 
717   return value;
718 }
719 
720 /* Find the next operand, and the operands value from ITER.  Return TRUE if
721    there is another operand, otherwise return FALSE.  If there is an
722    operand returned then the operand is placed into OPERAND, and the value
723    into VALUE.  If there is no operand returned then OPERAND and VALUE are
724    unchanged.  */
725 
726 static bfd_boolean
727 operand_iterator_next (struct arc_operand_iterator *iter,
728                        const struct arc_operand **operand,
729                        int *value)
730 {
731   if (*iter->opidx == 0)
732     {
733       *operand = NULL;
734       return FALSE;
735     }
736 
737   *operand = &arc_operands[*iter->opidx];
738   *value = extract_operand_value (*operand, iter->insn, iter->limm);
739   iter->opidx++;
740 
741   return TRUE;
742 }
743 
744 /* Helper for parsing the options.  */
745 
746 static void
747 parse_option (const char *option)
748 {
749   if (disassembler_options_cmp (option, "dsp") == 0)
750     add_to_decodelist (DSP, NONE);
751 
752   else if (disassembler_options_cmp (option, "spfp") == 0)
753     add_to_decodelist (FLOAT, SPX);
754 
755   else if (disassembler_options_cmp (option, "dpfp") == 0)
756     add_to_decodelist (FLOAT, DPX);
757 
758   else if (disassembler_options_cmp (option, "quarkse_em") == 0)
759     {
760       add_to_decodelist (FLOAT, DPX);
761       add_to_decodelist (FLOAT, SPX);
762       add_to_decodelist (FLOAT, QUARKSE1);
763       add_to_decodelist (FLOAT, QUARKSE2);
764     }
765 
766   else if (disassembler_options_cmp (option, "fpuda") == 0)
767     add_to_decodelist (FLOAT, DPA);
768 
769   else if (disassembler_options_cmp (option, "nps400") == 0)
770     {
771       add_to_decodelist (ACL, NPS400);
772       add_to_decodelist (ARITH, NPS400);
773       add_to_decodelist (BITOP, NPS400);
774       add_to_decodelist (BMU, NPS400);
775       add_to_decodelist (CONTROL, NPS400);
776       add_to_decodelist (DMA, NPS400);
777       add_to_decodelist (DPI, NPS400);
778       add_to_decodelist (MEMORY, NPS400);
779       add_to_decodelist (MISC, NPS400);
780       add_to_decodelist (NET, NPS400);
781       add_to_decodelist (PMU, NPS400);
782       add_to_decodelist (PROTOCOL_DECODE, NPS400);
783       add_to_decodelist (ULTRAIP, NPS400);
784     }
785 
786   else if (disassembler_options_cmp (option, "fpus") == 0)
787     {
788       add_to_decodelist (FLOAT, SP);
789       add_to_decodelist (FLOAT, CVT);
790     }
791 
792   else if (disassembler_options_cmp (option, "fpud") == 0)
793     {
794       add_to_decodelist (FLOAT, DP);
795       add_to_decodelist (FLOAT, CVT);
796     }
797   else if (CONST_STRNEQ (option, "hex"))
798     print_hex = TRUE;
799   else
800     /* xgettext:c-format */
801     opcodes_error_handler (_("unrecognised disassembler option: %s"), option);
802 }
803 
804 #define ARC_CPU_TYPE_A6xx(NAME,EXTRA)			\
805   { #NAME, ARC_OPCODE_ARC600, "ARC600" }
806 #define ARC_CPU_TYPE_A7xx(NAME,EXTRA)			\
807   { #NAME, ARC_OPCODE_ARC700, "ARC700" }
808 #define ARC_CPU_TYPE_AV2EM(NAME,EXTRA)			\
809   { #NAME,  ARC_OPCODE_ARCv2EM, "ARC EM" }
810 #define ARC_CPU_TYPE_AV2HS(NAME,EXTRA)			\
811   { #NAME,  ARC_OPCODE_ARCv2HS, "ARC HS" }
812 #define ARC_CPU_TYPE_NONE				\
813   { 0, 0, 0 }
814 
815 /* A table of CPU names and opcode sets.  */
816 static const struct cpu_type
817 {
818   const char *name;
819   unsigned flags;
820   const char *isa;
821 }
822   cpu_types[] =
823 {
824   #include "elf/arc-cpu.def"
825 };
826 
827 /* Helper for parsing the CPU options.  Accept any of the ARC architectures
828    values.  OPTION should be a value passed to cpu=.  */
829 
830 static unsigned
831 parse_cpu_option (const char *option)
832 {
833   int i;
834 
835   for (i = 0; cpu_types[i].name; ++i)
836     {
837       if (!disassembler_options_cmp (cpu_types[i].name, option))
838 	{
839 	  return cpu_types[i].flags;
840 	}
841     }
842 
843   /* xgettext:c-format */
844   opcodes_error_handler (_("unrecognised disassembler CPU option: %s"), option);
845   return ARC_OPCODE_NONE;
846 }
847 
848 /* Go over the options list and parse it.  */
849 
850 static void
851 parse_disassembler_options (const char *options)
852 {
853   const char *option;
854 
855   if (options == NULL)
856     return;
857 
858   /* Disassembler might be reused for difference CPU's, and cpu option set for
859      the first one shouldn't be applied to second (which might not have
860      explicit cpu in its options.  Therefore it is required to reset enforced
861      CPU when new options are being parsed.  */
862   enforced_isa_mask = ARC_OPCODE_NONE;
863 
864   FOR_EACH_DISASSEMBLER_OPTION (option, options)
865     {
866       /* A CPU option?  Cannot use STRING_COMMA_LEN because strncmp is also a
867 	 preprocessor macro.  */
868       if (strncmp (option, "cpu=", 4) == 0)
869 	/* Strip leading `cpu=`.  */
870 	enforced_isa_mask = parse_cpu_option (option + 4);
871       else
872 	parse_option (option);
873     }
874 }
875 
876 /* Return the instruction type for an instruction described by OPCODE.  */
877 
878 static enum dis_insn_type
879 arc_opcode_to_insn_type (const struct arc_opcode *opcode)
880 {
881   enum dis_insn_type insn_type;
882 
883   switch (opcode->insn_class)
884     {
885     case BRANCH:
886     case BBIT0:
887     case BBIT1:
888     case BI:
889     case BIH:
890     case BRCC:
891     case EI:
892     case JLI:
893     case JUMP:
894     case LOOP:
895       if (!strncmp (opcode->name, "bl", 2)
896 	  || !strncmp (opcode->name, "jl", 2))
897 	{
898 	  if (opcode->subclass == COND)
899 	    insn_type = dis_condjsr;
900 	  else
901 	    insn_type = dis_jsr;
902 	}
903       else
904 	{
905 	  if (opcode->subclass == COND)
906 	    insn_type = dis_condbranch;
907 	  else
908 	    insn_type = dis_branch;
909 	}
910       break;
911     case LOAD:
912     case STORE:
913     case MEMORY:
914     case ENTER:
915     case PUSH:
916     case POP:
917       insn_type = dis_dref;
918       break;
919     case LEAVE:
920       insn_type = dis_branch;
921       break;
922     default:
923       insn_type = dis_nonbranch;
924       break;
925     }
926 
927   return insn_type;
928 }
929 
930 /* Disassemble ARC instructions.  */
931 
932 static int
933 print_insn_arc (bfd_vma memaddr,
934 		struct disassemble_info *info)
935 {
936   bfd_byte buffer[8];
937   unsigned int highbyte, lowbyte;
938   int status;
939   unsigned int insn_len;
940   unsigned long long insn = 0;
941   unsigned isa_mask = ARC_OPCODE_NONE;
942   const struct arc_opcode *opcode;
943   bfd_boolean need_comma;
944   bfd_boolean open_braket;
945   int size;
946   const struct arc_operand *operand;
947   int value, vpcl;
948   struct arc_operand_iterator iter;
949   struct arc_disassemble_info *arc_infop;
950   bfd_boolean rpcl = FALSE, rset = FALSE;
951 
952   if (info->disassembler_options)
953     {
954       parse_disassembler_options (info->disassembler_options);
955 
956       /* Avoid repeated parsing of the options.  */
957       info->disassembler_options = NULL;
958     }
959 
960   if (info->private_data == NULL && !init_arc_disasm_info (info))
961     return -1;
962 
963   memset (&iter, 0, sizeof (iter));
964   highbyte  = ((info->endian == BFD_ENDIAN_LITTLE) ? 1 : 0);
965   lowbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 0 : 1);
966 
967   /* Figure out CPU type, unless it was enforced via disassembler options.  */
968   if (enforced_isa_mask == ARC_OPCODE_NONE)
969     {
970       Elf_Internal_Ehdr *header = NULL;
971 
972       if (info->section && info->section->owner)
973 	header = elf_elfheader (info->section->owner);
974 
975       switch (info->mach)
976 	{
977 	case bfd_mach_arc_arc700:
978 	  isa_mask = ARC_OPCODE_ARC700;
979 	  break;
980 
981 	case bfd_mach_arc_arc600:
982 	  isa_mask = ARC_OPCODE_ARC600;
983 	  break;
984 
985 	case bfd_mach_arc_arcv2:
986 	default:
987 	  isa_mask = ARC_OPCODE_ARCv2EM;
988 	  /* TODO: Perhaps remove definition of header since it is only used at
989 	     this location.  */
990 	  if (header != NULL
991 	      && (header->e_flags & EF_ARC_MACH_MSK) == EF_ARC_CPU_ARCV2HS)
992 	    isa_mask = ARC_OPCODE_ARCv2HS;
993 	  break;
994 	}
995     }
996   else
997     isa_mask = enforced_isa_mask;
998 
999   if (isa_mask == ARC_OPCODE_ARCv2HS)
1000     {
1001       /* FPU instructions are not extensions for HS.  */
1002       add_to_decodelist (FLOAT, SP);
1003       add_to_decodelist (FLOAT, DP);
1004       add_to_decodelist (FLOAT, CVT);
1005     }
1006 
1007   /* This variable may be set by the instruction decoder.  It suggests
1008      the number of bytes objdump should display on a single line.  If
1009      the instruction decoder sets this, it should always set it to
1010      the same value in order to get reasonable looking output.  */
1011   info->bytes_per_line  = 8;
1012 
1013   /* In the next lines, we set two info variables control the way
1014      objdump displays the raw data.  For example, if bytes_per_line is
1015      8 and bytes_per_chunk is 4, the output will look like this:
1016      00:   00000000 00000000
1017      with the chunks displayed according to "display_endian".  */
1018   if (info->section
1019       && !(info->section->flags & SEC_CODE))
1020     {
1021       /* This is not a CODE section.  */
1022       switch (info->section->size)
1023 	{
1024 	case 1:
1025 	case 2:
1026 	case 4:
1027 	  size = info->section->size;
1028 	  break;
1029 	default:
1030 	  size = (info->section->size & 0x01) ? 1 : 4;
1031 	  break;
1032 	}
1033       info->bytes_per_chunk = 1;
1034       info->display_endian = info->endian;
1035     }
1036   else
1037     {
1038       size = 2;
1039       info->bytes_per_chunk = 2;
1040       info->display_endian = info->endian;
1041     }
1042 
1043   /* Read the insn into a host word.  */
1044   status = (*info->read_memory_func) (memaddr, buffer, size, info);
1045 
1046   if (status != 0)
1047     {
1048       (*info->memory_error_func) (status, memaddr, info);
1049       return -1;
1050     }
1051 
1052   if (info->section
1053       && !(info->section->flags & SEC_CODE))
1054     {
1055       /* Data section.  */
1056       unsigned long data;
1057 
1058       data = bfd_get_bits (buffer, size * 8,
1059 			   info->display_endian == BFD_ENDIAN_BIG);
1060       switch (size)
1061 	{
1062 	case 1:
1063 	  (*info->fprintf_func) (info->stream, ".byte\t0x%02lx", data);
1064 	  break;
1065 	case 2:
1066 	  (*info->fprintf_func) (info->stream, ".short\t0x%04lx", data);
1067 	  break;
1068 	case 4:
1069 	  (*info->fprintf_func) (info->stream, ".word\t0x%08lx", data);
1070 	  break;
1071 	default:
1072 	  return -1;
1073 	}
1074       return size;
1075     }
1076 
1077   insn_len = arc_insn_length (buffer[highbyte], buffer[lowbyte], info);
1078   pr_debug ("instruction length = %d bytes\n", insn_len);
1079   if (insn_len == 0)
1080     return -1;
1081 
1082   arc_infop = info->private_data;
1083   arc_infop->insn_len = insn_len;
1084 
1085   switch (insn_len)
1086     {
1087     case 2:
1088       insn = (buffer[highbyte] << 8) | buffer[lowbyte];
1089       break;
1090 
1091     case 4:
1092       {
1093 	/* This is a long instruction: Read the remaning 2 bytes.  */
1094 	status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 2, info);
1095 	if (status != 0)
1096 	  {
1097 	    (*info->memory_error_func) (status, memaddr + 2, info);
1098 	    return -1;
1099 	  }
1100 	insn = (unsigned long long) ARRANGE_ENDIAN (info, buffer);
1101       }
1102       break;
1103 
1104     case 6:
1105       {
1106 	status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 4, info);
1107 	if (status != 0)
1108 	  {
1109 	    (*info->memory_error_func) (status, memaddr + 2, info);
1110 	    return -1;
1111 	  }
1112 	insn = (unsigned long long) ARRANGE_ENDIAN (info, &buffer[2]);
1113 	insn |= ((unsigned long long) buffer[highbyte] << 40)
1114 	  | ((unsigned long long) buffer[lowbyte] << 32);
1115       }
1116       break;
1117 
1118     case 8:
1119       {
1120 	status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 6, info);
1121 	if (status != 0)
1122 	  {
1123 	    (*info->memory_error_func) (status, memaddr + 2, info);
1124 	    return -1;
1125 	  }
1126 	insn =
1127 	  ((((unsigned long long) ARRANGE_ENDIAN (info, buffer)) << 32)
1128 	   | ((unsigned long long) ARRANGE_ENDIAN (info, &buffer[4])));
1129       }
1130       break;
1131 
1132     default:
1133       /* There is no instruction whose length is not 2, 4, 6, or 8.  */
1134       return -1;
1135     }
1136 
1137   pr_debug ("instruction value = %llx\n", insn);
1138 
1139   /* Set some defaults for the insn info.  */
1140   info->insn_info_valid    = 1;
1141   info->branch_delay_insns = 0;
1142   info->data_size	   = 4;
1143   info->insn_type	   = dis_nonbranch;
1144   info->target		   = 0;
1145   info->target2		   = 0;
1146 
1147   /* FIXME to be moved in dissasemble_init_for_target.  */
1148   info->disassembler_needs_relocs = TRUE;
1149 
1150   /* Find the first match in the opcode table.  */
1151   if (!find_format (memaddr, insn, &insn_len, isa_mask, info, &opcode, &iter))
1152     return -1;
1153 
1154   if (!opcode)
1155     {
1156       switch (insn_len)
1157 	{
1158 	case 2:
1159 	  (*info->fprintf_func) (info->stream, ".shor\t%#04llx",
1160 				 insn & 0xffff);
1161 	  break;
1162 
1163 	case 4:
1164 	  (*info->fprintf_func) (info->stream, ".word\t%#08llx",
1165 				 insn & 0xffffffff);
1166 	  break;
1167 
1168 	case 6:
1169 	  (*info->fprintf_func) (info->stream, ".long\t%#08llx",
1170 				 insn & 0xffffffff);
1171 	  (*info->fprintf_func) (info->stream, ".long\t%#04llx",
1172 				 (insn >> 32) & 0xffff);
1173 	  break;
1174 
1175 	case 8:
1176 	  (*info->fprintf_func) (info->stream, ".long\t%#08llx",
1177 				 insn & 0xffffffff);
1178 	  (*info->fprintf_func) (info->stream, ".long\t%#08llx",
1179 				 insn >> 32);
1180 	  break;
1181 
1182 	default:
1183 	  return -1;
1184 	}
1185 
1186       info->insn_type = dis_noninsn;
1187       return insn_len;
1188     }
1189 
1190   /* Print the mnemonic.  */
1191   (*info->fprintf_func) (info->stream, "%s", opcode->name);
1192 
1193   /* Preselect the insn class.  */
1194   info->insn_type = arc_opcode_to_insn_type (opcode);
1195 
1196   pr_debug ("%s: 0x%08llx\n", opcode->name, opcode->opcode);
1197 
1198   print_flags (opcode, &insn, info);
1199 
1200   if (opcode->operands[0] != 0)
1201     (*info->fprintf_func) (info->stream, "\t");
1202 
1203   need_comma = FALSE;
1204   open_braket = FALSE;
1205   arc_infop->operands_count = 0;
1206 
1207   /* Now extract and print the operands.  */
1208   operand = NULL;
1209   vpcl = 0;
1210   while (operand_iterator_next (&iter, &operand, &value))
1211     {
1212       if (open_braket && (operand->flags & ARC_OPERAND_BRAKET))
1213 	{
1214 	  (*info->fprintf_func) (info->stream, "]");
1215 	  open_braket = FALSE;
1216 	  continue;
1217 	}
1218 
1219       /* Only take input from real operands.  */
1220       if (ARC_OPERAND_IS_FAKE (operand))
1221 	continue;
1222 
1223       if ((operand->flags & ARC_OPERAND_IGNORE)
1224 	  && (operand->flags & ARC_OPERAND_IR)
1225 	  && value == -1)
1226 	continue;
1227 
1228       if (operand->flags & ARC_OPERAND_COLON)
1229 	{
1230 	  (*info->fprintf_func) (info->stream, ":");
1231 	  continue;
1232 	}
1233 
1234       if (need_comma)
1235 	(*info->fprintf_func) (info->stream, ",");
1236 
1237       if (!open_braket && (operand->flags & ARC_OPERAND_BRAKET))
1238 	{
1239 	  (*info->fprintf_func) (info->stream, "[");
1240 	  open_braket = TRUE;
1241 	  need_comma = FALSE;
1242 	  continue;
1243 	}
1244 
1245       need_comma = TRUE;
1246 
1247       if (operand->flags & ARC_OPERAND_PCREL)
1248 	{
1249 	  rpcl = TRUE;
1250 	  vpcl = value;
1251 	  rset = TRUE;
1252 
1253 	  info->target = (bfd_vma) (memaddr & ~3) + value;
1254 	}
1255       else if (!(operand->flags & ARC_OPERAND_IR))
1256 	{
1257 	  vpcl = value;
1258 	  rset = TRUE;
1259 	}
1260 
1261       /* Print the operand as directed by the flags.  */
1262       if (operand->flags & ARC_OPERAND_IR)
1263 	{
1264 	  const char *rname;
1265 
1266 	  assert (value >=0 && value < 64);
1267 	  rname = arcExtMap_coreRegName (value);
1268 	  if (!rname)
1269 	    rname = regnames[value];
1270 	  (*info->fprintf_func) (info->stream, "%s", rname);
1271 	  if (operand->flags & ARC_OPERAND_TRUNCATE)
1272 	    {
1273 	      rname = arcExtMap_coreRegName (value + 1);
1274 	      if (!rname)
1275 		rname = regnames[value + 1];
1276 	      (*info->fprintf_func) (info->stream, "%s", rname);
1277 	    }
1278 	  if (value == 63)
1279 	    rpcl = TRUE;
1280 	  else
1281 	    rpcl = FALSE;
1282 	}
1283       else if (operand->flags & ARC_OPERAND_LIMM)
1284 	{
1285 	  const char *rname = get_auxreg (opcode, value, isa_mask);
1286 
1287 	  if (rname && open_braket)
1288 	    (*info->fprintf_func) (info->stream, "%s", rname);
1289 	  else
1290 	    {
1291 	      (*info->fprintf_func) (info->stream, "%#x", value);
1292 	      if (info->insn_type == dis_branch
1293 		  || info->insn_type == dis_jsr)
1294 		info->target = (bfd_vma) value;
1295 	    }
1296 	}
1297       else if (operand->flags & ARC_OPERAND_SIGNED)
1298 	{
1299 	  const char *rname = get_auxreg (opcode, value, isa_mask);
1300 	  if (rname && open_braket)
1301 	    (*info->fprintf_func) (info->stream, "%s", rname);
1302 	  else
1303 	    {
1304 	      if (print_hex)
1305 		(*info->fprintf_func) (info->stream, "%#x", value);
1306 	      else
1307 		(*info->fprintf_func) (info->stream, "%d", value);
1308 	    }
1309 	}
1310       else if (operand->flags & ARC_OPERAND_ADDRTYPE)
1311 	{
1312 	  const char *addrtype = get_addrtype (value);
1313 	  (*info->fprintf_func) (info->stream, "%s", addrtype);
1314 	  /* A colon follow an address type.  */
1315 	  need_comma = FALSE;
1316 	}
1317       else
1318 	{
1319 	  if (operand->flags & ARC_OPERAND_TRUNCATE
1320 	      && !(operand->flags & ARC_OPERAND_ALIGNED32)
1321 	      && !(operand->flags & ARC_OPERAND_ALIGNED16)
1322 	      && value >= 0 && value <= 14)
1323 	    {
1324 	      /* Leave/Enter mnemonics.  */
1325 	      switch (value)
1326 		{
1327 		case 0:
1328 		  need_comma = FALSE;
1329 		  break;
1330 		case 1:
1331 		  (*info->fprintf_func) (info->stream, "r13");
1332 		  break;
1333 		default:
1334 		  (*info->fprintf_func) (info->stream, "r13-%s",
1335 					 regnames[13 + value - 1]);
1336 		  break;
1337 		}
1338 	      rpcl = FALSE;
1339 	      rset = FALSE;
1340 	    }
1341 	  else
1342 	    {
1343 	      const char *rname = get_auxreg (opcode, value, isa_mask);
1344 	      if (rname && open_braket)
1345 		(*info->fprintf_func) (info->stream, "%s", rname);
1346 	      else
1347 		(*info->fprintf_func) (info->stream, "%#x", value);
1348 	    }
1349 	}
1350 
1351       if (operand->flags & ARC_OPERAND_LIMM)
1352 	{
1353 	  arc_infop->operands[arc_infop->operands_count].kind
1354 	    = ARC_OPERAND_KIND_LIMM;
1355 	  /* It is not important to have exactly the LIMM indicator
1356 	     here.  */
1357 	  arc_infop->operands[arc_infop->operands_count].value = 63;
1358 	}
1359       else
1360 	{
1361 	  arc_infop->operands[arc_infop->operands_count].value = value;
1362 	  arc_infop->operands[arc_infop->operands_count].kind
1363 	    = (operand->flags & ARC_OPERAND_IR
1364 	       ? ARC_OPERAND_KIND_REG
1365 	       : ARC_OPERAND_KIND_SHIMM);
1366 	}
1367       arc_infop->operands_count ++;
1368     }
1369 
1370   /* Pretty print extra info for pc-relative operands.  */
1371   if (rpcl && rset)
1372     {
1373       if (info->flags & INSN_HAS_RELOC)
1374 	/* If the instruction has a reloc associated with it, then the
1375 	   offset field in the instruction will actually be the addend
1376 	   for the reloc.  (We are using REL type relocs).  In such
1377 	   cases, we can ignore the pc when computing addresses, since
1378 	   the addend is not currently pc-relative.  */
1379 	memaddr = 0;
1380 
1381       (*info->fprintf_func) (info->stream, "\t;");
1382       (*info->print_address_func) ((memaddr & ~3) + vpcl, info);
1383     }
1384 
1385   return insn_len;
1386 }
1387 
1388 
1389 disassembler_ftype
1390 arc_get_disassembler (bfd *abfd)
1391 {
1392   /* BFD my be absent, if opcodes is invoked from the debugger that
1393      has connected to remote target and doesn't have an ELF file.  */
1394   if (abfd != NULL)
1395     {
1396       /* Read the extension insns and registers, if any.  */
1397       build_ARC_extmap (abfd);
1398 #ifdef DEBUG
1399       dump_ARC_extmap ();
1400 #endif
1401     }
1402 
1403   return print_insn_arc;
1404 }
1405 
1406 void
1407 print_arc_disassembler_options (FILE *stream)
1408 {
1409   int i;
1410 
1411   fprintf (stream, _("\n\
1412 The following ARC specific disassembler options are supported for use \n\
1413 with -M switch (multiple options should be separated by commas):\n"));
1414 
1415   /* cpu=... options.  */
1416   for (i = 0; cpu_types[i].name; ++i)
1417     {
1418       /* As of now all value CPU values are less than 16 characters.  */
1419       fprintf (stream, "  cpu=%-16s\tEnforce %s ISA.\n",
1420 	       cpu_types[i].name, cpu_types[i].isa);
1421     }
1422 
1423   fprintf (stream, _("\
1424   dsp             Recognize DSP instructions.\n"));
1425   fprintf (stream, _("\
1426   spfp            Recognize FPX SP instructions.\n"));
1427   fprintf (stream, _("\
1428   dpfp            Recognize FPX DP instructions.\n"));
1429   fprintf (stream, _("\
1430   quarkse_em      Recognize FPU QuarkSE-EM instructions.\n"));
1431   fprintf (stream, _("\
1432   fpuda           Recognize double assist FPU instructions.\n"));
1433   fprintf (stream, _("\
1434   fpus            Recognize single precision FPU instructions.\n"));
1435   fprintf (stream, _("\
1436   fpud            Recognize double precision FPU instructions.\n"));
1437   fprintf (stream, _("\
1438   nps400          Recognize NPS400 instructions.\n"));
1439   fprintf (stream, _("\
1440   hex             Use only hexadecimal number to print immediates.\n"));
1441 }
1442 
1443 void arc_insn_decode (bfd_vma addr,
1444 		      struct disassemble_info *info,
1445 		      disassembler_ftype disasm_func,
1446 		      struct arc_instruction *insn)
1447 {
1448   const struct arc_opcode *opcode;
1449   struct arc_disassemble_info *arc_infop;
1450 
1451   /* Ensure that insn would be in the reset state.  */
1452   memset (insn, 0, sizeof (struct arc_instruction));
1453 
1454   /* There was an error when disassembling, for example memory read error.  */
1455   if (disasm_func (addr, info) < 0)
1456     {
1457       insn->valid = FALSE;
1458       return;
1459     }
1460 
1461   assert (info->private_data != NULL);
1462   arc_infop = info->private_data;
1463 
1464   insn->length  = arc_infop->insn_len;;
1465   insn->address = addr;
1466 
1467   /* Quick exit if memory at this address is not an instruction.  */
1468   if (info->insn_type == dis_noninsn)
1469     {
1470       insn->valid = FALSE;
1471       return;
1472     }
1473 
1474   insn->valid = TRUE;
1475 
1476   opcode = (const struct arc_opcode *) arc_infop->opcode;
1477   insn->insn_class = opcode->insn_class;
1478   insn->limm_value = arc_infop->limm;
1479   insn->limm_p     = arc_infop->limm_p;
1480 
1481   insn->is_control_flow = (info->insn_type == dis_branch
1482 			   || info->insn_type == dis_condbranch
1483 			   || info->insn_type == dis_jsr
1484 			   || info->insn_type == dis_condjsr);
1485 
1486   insn->has_delay_slot = info->branch_delay_insns;
1487   insn->writeback_mode
1488     = (enum arc_ldst_writeback_mode) arc_infop->writeback_mode;
1489   insn->data_size_mode = info->data_size;
1490   insn->condition_code = arc_infop->condition_code;
1491   memcpy (insn->operands, arc_infop->operands,
1492 	  sizeof (struct arc_insn_operand) * MAX_INSN_ARGS);
1493   insn->operands_count = arc_infop->operands_count;
1494 }
1495 
1496 /* Local variables:
1497    eval: (c-set-style "gnu")
1498    indent-tabs-mode: t
1499    End:  */
1500