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