xref: /netbsd-src/external/gpl3/binutils/dist/opcodes/arc-dis.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
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     fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
782 }
783 
784 #define ARC_CPU_TYPE_A6xx(NAME,EXTRA)			\
785   { #NAME, ARC_OPCODE_ARC600, "ARC600" }
786 #define ARC_CPU_TYPE_A7xx(NAME,EXTRA)			\
787   { #NAME, ARC_OPCODE_ARC700, "ARC700" }
788 #define ARC_CPU_TYPE_AV2EM(NAME,EXTRA)			\
789   { #NAME,  ARC_OPCODE_ARCv2EM, "ARC EM" }
790 #define ARC_CPU_TYPE_AV2HS(NAME,EXTRA)			\
791   { #NAME,  ARC_OPCODE_ARCv2HS, "ARC HS" }
792 #define ARC_CPU_TYPE_NONE				\
793   { 0, 0, 0 }
794 
795 /* A table of CPU names and opcode sets.  */
796 static const struct cpu_type
797 {
798   const char *name;
799   unsigned flags;
800   const char *isa;
801 }
802   cpu_types[] =
803 {
804   #include "elf/arc-cpu.def"
805 };
806 
807 /* Helper for parsing the CPU options.  Accept any of the ARC architectures
808    values.  OPTION should be a value passed to cpu=.  */
809 
810 static unsigned
811 parse_cpu_option (const char *option)
812 {
813   int i;
814 
815   for (i = 0; cpu_types[i].name; ++i)
816     {
817       if (!disassembler_options_cmp (cpu_types[i].name, option))
818 	{
819 	  return cpu_types[i].flags;
820 	}
821     }
822 
823   fprintf (stderr, _("Unrecognised disassembler CPU option: %s\n"), option);
824   return ARC_OPCODE_NONE;
825 }
826 
827 /* Go over the options list and parse it.  */
828 
829 static void
830 parse_disassembler_options (const char *options)
831 {
832   const char *option;
833 
834   if (options == NULL)
835     return;
836 
837   /* Disassembler might be reused for difference CPU's, and cpu option set for
838      the first one shouldn't be applied to second (which might not have
839      explicit cpu in its options.  Therefore it is required to reset enforced
840      CPU when new options are being parsed.  */
841   enforced_isa_mask = ARC_OPCODE_NONE;
842 
843   FOR_EACH_DISASSEMBLER_OPTION (option, options)
844     {
845       /* A CPU option?  Cannot use STRING_COMMA_LEN because strncmp is also a
846 	 preprocessor macro.  */
847       if (strncmp (option, "cpu=", 4) == 0)
848 	/* Strip leading `cpu=`.  */
849 	enforced_isa_mask = parse_cpu_option (option + 4);
850       else
851 	parse_option (option);
852     }
853 }
854 
855 /* Return the instruction type for an instruction described by OPCODE.  */
856 
857 static enum dis_insn_type
858 arc_opcode_to_insn_type (const struct arc_opcode *opcode)
859 {
860   enum dis_insn_type insn_type;
861 
862   switch (opcode->insn_class)
863     {
864     case BRANCH:
865     case BBIT0:
866     case BBIT1:
867     case BI:
868     case BIH:
869     case BRCC:
870     case EI:
871     case JLI:
872     case JUMP:
873     case LOOP:
874       if (!strncmp (opcode->name, "bl", 2)
875 	  || !strncmp (opcode->name, "jl", 2))
876 	{
877 	  if (opcode->subclass == COND)
878 	    insn_type = dis_condjsr;
879 	  else
880 	    insn_type = dis_jsr;
881 	}
882       else
883 	{
884 	  if (opcode->subclass == COND)
885 	    insn_type = dis_condbranch;
886 	  else
887 	    insn_type = dis_branch;
888 	}
889       break;
890     case LOAD:
891     case STORE:
892     case MEMORY:
893     case ENTER:
894     case PUSH:
895     case POP:
896       insn_type = dis_dref;
897       break;
898     case LEAVE:
899       insn_type = dis_branch;
900       break;
901     default:
902       insn_type = dis_nonbranch;
903       break;
904     }
905 
906   return insn_type;
907 }
908 
909 /* Disassemble ARC instructions.  */
910 
911 static int
912 print_insn_arc (bfd_vma memaddr,
913 		struct disassemble_info *info)
914 {
915   bfd_byte buffer[8];
916   unsigned int highbyte, lowbyte;
917   int status;
918   unsigned int insn_len;
919   unsigned long long insn = 0;
920   unsigned isa_mask = ARC_OPCODE_NONE;
921   const struct arc_opcode *opcode;
922   bfd_boolean need_comma;
923   bfd_boolean open_braket;
924   int size;
925   const struct arc_operand *operand;
926   int value, vpcl;
927   struct arc_operand_iterator iter;
928   struct arc_disassemble_info *arc_infop;
929   bfd_boolean rpcl = FALSE, rset = FALSE;
930 
931   if (info->disassembler_options)
932     {
933       parse_disassembler_options (info->disassembler_options);
934 
935       /* Avoid repeated parsing of the options.  */
936       info->disassembler_options = NULL;
937     }
938 
939   if (info->private_data == NULL && !init_arc_disasm_info (info))
940     return -1;
941 
942   memset (&iter, 0, sizeof (iter));
943   highbyte  = ((info->endian == BFD_ENDIAN_LITTLE) ? 1 : 0);
944   lowbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 0 : 1);
945 
946   /* Figure out CPU type, unless it was enforced via disassembler options.  */
947   if (enforced_isa_mask == ARC_OPCODE_NONE)
948     {
949       Elf_Internal_Ehdr *header = NULL;
950 
951       if (info->section && info->section->owner)
952 	header = elf_elfheader (info->section->owner);
953 
954       switch (info->mach)
955 	{
956 	case bfd_mach_arc_arc700:
957 	  isa_mask = ARC_OPCODE_ARC700;
958 	  break;
959 
960 	case bfd_mach_arc_arc600:
961 	  isa_mask = ARC_OPCODE_ARC600;
962 	  break;
963 
964 	case bfd_mach_arc_arcv2:
965 	default:
966 	  isa_mask = ARC_OPCODE_ARCv2EM;
967 	  /* TODO: Perhaps remove definition of header since it is only used at
968 	     this location.  */
969 	  if (header != NULL
970 	      && (header->e_flags & EF_ARC_MACH_MSK) == EF_ARC_CPU_ARCV2HS)
971 	    isa_mask = ARC_OPCODE_ARCv2HS;
972 	  break;
973 	}
974     }
975   else
976     isa_mask = enforced_isa_mask;
977 
978   if (isa_mask == ARC_OPCODE_ARCv2HS)
979     {
980       /* FPU instructions are not extensions for HS.  */
981       add_to_decodelist (FLOAT, SP);
982       add_to_decodelist (FLOAT, DP);
983       add_to_decodelist (FLOAT, CVT);
984     }
985 
986   /* This variable may be set by the instruction decoder.  It suggests
987      the number of bytes objdump should display on a single line.  If
988      the instruction decoder sets this, it should always set it to
989      the same value in order to get reasonable looking output.  */
990 
991   info->bytes_per_line  = 8;
992 
993   /* In the next lines, we set two info variables control the way
994      objdump displays the raw data.  For example, if bytes_per_line is
995      8 and bytes_per_chunk is 4, the output will look like this:
996      00:   00000000 00000000
997      with the chunks displayed according to "display_endian".  */
998 
999   if (info->section
1000       && !(info->section->flags & SEC_CODE))
1001     {
1002       /* This is not a CODE section.  */
1003       switch (info->section->size)
1004 	{
1005 	case 1:
1006 	case 2:
1007 	case 4:
1008 	  size = info->section->size;
1009 	  break;
1010 	default:
1011 	  size = (info->section->size & 0x01) ? 1 : 4;
1012 	  break;
1013 	}
1014       info->bytes_per_chunk = 1;
1015       info->display_endian = info->endian;
1016     }
1017   else
1018     {
1019       size = 2;
1020       info->bytes_per_chunk = 2;
1021       info->display_endian = info->endian;
1022     }
1023 
1024   /* Read the insn into a host word.  */
1025   status = (*info->read_memory_func) (memaddr, buffer, size, info);
1026 
1027   if (status != 0)
1028     {
1029       (*info->memory_error_func) (status, memaddr, info);
1030       return -1;
1031     }
1032 
1033   if (info->section
1034       && !(info->section->flags & SEC_CODE))
1035     {
1036       /* Data section.  */
1037       unsigned long data;
1038 
1039       data = bfd_get_bits (buffer, size * 8,
1040 			   info->display_endian == BFD_ENDIAN_BIG);
1041       switch (size)
1042 	{
1043 	case 1:
1044 	  (*info->fprintf_func) (info->stream, ".byte\t0x%02lx", data);
1045 	  break;
1046 	case 2:
1047 	  (*info->fprintf_func) (info->stream, ".short\t0x%04lx", data);
1048 	  break;
1049 	case 4:
1050 	  (*info->fprintf_func) (info->stream, ".word\t0x%08lx", data);
1051 	  break;
1052 	default:
1053 	  abort ();
1054 	}
1055       return size;
1056     }
1057 
1058   insn_len = arc_insn_length (buffer[highbyte], buffer[lowbyte], info);
1059   pr_debug ("instruction length = %d bytes\n", insn_len);
1060   arc_infop = info->private_data;
1061   arc_infop->insn_len = insn_len;
1062 
1063   switch (insn_len)
1064     {
1065     case 2:
1066       insn = (buffer[highbyte] << 8) | buffer[lowbyte];
1067       break;
1068 
1069     case 4:
1070       {
1071 	/* This is a long instruction: Read the remaning 2 bytes.  */
1072 	status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 2, info);
1073 	if (status != 0)
1074 	  {
1075 	    (*info->memory_error_func) (status, memaddr + 2, info);
1076 	    return -1;
1077 	  }
1078 	insn = (unsigned long long) ARRANGE_ENDIAN (info, buffer);
1079       }
1080       break;
1081 
1082     case 6:
1083       {
1084 	status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 4, info);
1085 	if (status != 0)
1086 	  {
1087 	    (*info->memory_error_func) (status, memaddr + 2, info);
1088 	    return -1;
1089 	  }
1090 	insn = (unsigned long long) ARRANGE_ENDIAN (info, &buffer[2]);
1091 	insn |= ((unsigned long long) buffer[highbyte] << 40)
1092 	  | ((unsigned long long) buffer[lowbyte] << 32);
1093       }
1094       break;
1095 
1096     case 8:
1097       {
1098 	status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 6, info);
1099 	if (status != 0)
1100 	  {
1101 	    (*info->memory_error_func) (status, memaddr + 2, info);
1102 	    return -1;
1103 	  }
1104 	insn =
1105 	  ((((unsigned long long) ARRANGE_ENDIAN (info, buffer)) << 32)
1106 	   | ((unsigned long long) ARRANGE_ENDIAN (info, &buffer[4])));
1107       }
1108       break;
1109 
1110     default:
1111       /* There is no instruction whose length is not 2, 4, 6, or 8.  */
1112       abort ();
1113     }
1114 
1115   pr_debug ("instruction value = %llx\n", insn);
1116 
1117   /* Set some defaults for the insn info.  */
1118   info->insn_info_valid    = 1;
1119   info->branch_delay_insns = 0;
1120   info->data_size	   = 4;
1121   info->insn_type	   = dis_nonbranch;
1122   info->target		   = 0;
1123   info->target2		   = 0;
1124 
1125   /* FIXME to be moved in dissasemble_init_for_target.  */
1126   info->disassembler_needs_relocs = TRUE;
1127 
1128   /* Find the first match in the opcode table.  */
1129   if (!find_format (memaddr, insn, &insn_len, isa_mask, info, &opcode, &iter))
1130     return -1;
1131 
1132   if (!opcode)
1133     {
1134       switch (insn_len)
1135 	{
1136 	case 2:
1137 	  (*info->fprintf_func) (info->stream, ".shor\t%#04llx",
1138 				 insn & 0xffff);
1139 	  break;
1140 	case 4:
1141 	  (*info->fprintf_func) (info->stream, ".word\t%#08llx",
1142 				 insn & 0xffffffff);
1143 	  break;
1144 	case 6:
1145 	  (*info->fprintf_func) (info->stream, ".long\t%#08llx",
1146 				 insn & 0xffffffff);
1147 	  (*info->fprintf_func) (info->stream, ".long\t%#04llx",
1148 				 (insn >> 32) & 0xffff);
1149 	  break;
1150 	case 8:
1151 	  (*info->fprintf_func) (info->stream, ".long\t%#08llx",
1152 				 insn & 0xffffffff);
1153 	  (*info->fprintf_func) (info->stream, ".long\t%#08llx",
1154 				 insn >> 32);
1155 	  break;
1156 	default:
1157 	  abort ();
1158 	}
1159 
1160       info->insn_type = dis_noninsn;
1161       return insn_len;
1162     }
1163 
1164   /* Print the mnemonic.  */
1165   (*info->fprintf_func) (info->stream, "%s", opcode->name);
1166 
1167   /* Preselect the insn class.  */
1168   info->insn_type = arc_opcode_to_insn_type (opcode);
1169 
1170   pr_debug ("%s: 0x%08llx\n", opcode->name, opcode->opcode);
1171 
1172   print_flags (opcode, &insn, info);
1173 
1174   if (opcode->operands[0] != 0)
1175     (*info->fprintf_func) (info->stream, "\t");
1176 
1177   need_comma = FALSE;
1178   open_braket = FALSE;
1179   arc_infop->operands_count = 0;
1180 
1181   /* Now extract and print the operands.  */
1182   operand = NULL;
1183   vpcl = 0;
1184   while (operand_iterator_next (&iter, &operand, &value))
1185     {
1186       if (open_braket && (operand->flags & ARC_OPERAND_BRAKET))
1187 	{
1188 	  (*info->fprintf_func) (info->stream, "]");
1189 	  open_braket = FALSE;
1190 	  continue;
1191 	}
1192 
1193       /* Only take input from real operands.  */
1194       if (ARC_OPERAND_IS_FAKE (operand))
1195 	continue;
1196 
1197       if ((operand->flags & ARC_OPERAND_IGNORE)
1198 	  && (operand->flags & ARC_OPERAND_IR)
1199 	  && value == -1)
1200 	continue;
1201 
1202       if (operand->flags & ARC_OPERAND_COLON)
1203 	{
1204 	  (*info->fprintf_func) (info->stream, ":");
1205 	  continue;
1206 	}
1207 
1208       if (need_comma)
1209 	(*info->fprintf_func) (info->stream, ",");
1210 
1211       if (!open_braket && (operand->flags & ARC_OPERAND_BRAKET))
1212 	{
1213 	  (*info->fprintf_func) (info->stream, "[");
1214 	  open_braket = TRUE;
1215 	  need_comma = FALSE;
1216 	  continue;
1217 	}
1218 
1219       need_comma = TRUE;
1220 
1221       if (operand->flags & ARC_OPERAND_PCREL)
1222 	{
1223 	  rpcl = TRUE;
1224 	  vpcl = value;
1225 	  rset = TRUE;
1226 
1227 	  info->target = (bfd_vma) (memaddr & ~3) + value;
1228 	}
1229       else if (!(operand->flags & ARC_OPERAND_IR))
1230 	{
1231 	  vpcl = value;
1232 	  rset = TRUE;
1233 	}
1234 
1235       /* Print the operand as directed by the flags.  */
1236       if (operand->flags & ARC_OPERAND_IR)
1237 	{
1238 	  const char *rname;
1239 
1240 	  assert (value >=0 && value < 64);
1241 	  rname = arcExtMap_coreRegName (value);
1242 	  if (!rname)
1243 	    rname = regnames[value];
1244 	  (*info->fprintf_func) (info->stream, "%s", rname);
1245 	  if (operand->flags & ARC_OPERAND_TRUNCATE)
1246 	    {
1247 	      rname = arcExtMap_coreRegName (value + 1);
1248 	      if (!rname)
1249 		rname = regnames[value + 1];
1250 	      (*info->fprintf_func) (info->stream, "%s", rname);
1251 	    }
1252 	  if (value == 63)
1253 	    rpcl = TRUE;
1254 	  else
1255 	    rpcl = FALSE;
1256 	}
1257       else if (operand->flags & ARC_OPERAND_LIMM)
1258 	{
1259 	  const char *rname = get_auxreg (opcode, value, isa_mask);
1260 
1261 	  if (rname && open_braket)
1262 	    (*info->fprintf_func) (info->stream, "%s", rname);
1263 	  else
1264 	    {
1265 	      (*info->fprintf_func) (info->stream, "%#x", value);
1266 	      if (info->insn_type == dis_branch
1267 		  || info->insn_type == dis_jsr)
1268 		info->target = (bfd_vma) value;
1269 	    }
1270 	}
1271       else if (operand->flags & ARC_OPERAND_SIGNED)
1272 	{
1273 	  const char *rname = get_auxreg (opcode, value, isa_mask);
1274 	  if (rname && open_braket)
1275 	    (*info->fprintf_func) (info->stream, "%s", rname);
1276 	  else
1277 	    {
1278 	      if (print_hex)
1279 		(*info->fprintf_func) (info->stream, "%#x", value);
1280 	      else
1281 		(*info->fprintf_func) (info->stream, "%d", value);
1282 	    }
1283 	}
1284       else if (operand->flags & ARC_OPERAND_ADDRTYPE)
1285 	{
1286 	  const char *addrtype = get_addrtype (value);
1287 	  (*info->fprintf_func) (info->stream, "%s", addrtype);
1288 	  /* A colon follow an address type.  */
1289 	  need_comma = FALSE;
1290 	}
1291       else
1292 	{
1293 	  if (operand->flags & ARC_OPERAND_TRUNCATE
1294 	      && !(operand->flags & ARC_OPERAND_ALIGNED32)
1295 	      && !(operand->flags & ARC_OPERAND_ALIGNED16)
1296 	      && value >= 0 && value <= 14)
1297 	    {
1298 	      /* Leave/Enter mnemonics.  */
1299 	      switch (value)
1300 		{
1301 		case 0:
1302 		  need_comma = FALSE;
1303 		  break;
1304 		case 1:
1305 		  (*info->fprintf_func) (info->stream, "r13");
1306 		  break;
1307 		default:
1308 		  (*info->fprintf_func) (info->stream, "r13-%s",
1309 					 regnames[13 + value - 1]);
1310 		  break;
1311 		}
1312 	      rpcl = FALSE;
1313 	      rset = FALSE;
1314 	    }
1315 	  else
1316 	    {
1317 	      const char *rname = get_auxreg (opcode, value, isa_mask);
1318 	      if (rname && open_braket)
1319 		(*info->fprintf_func) (info->stream, "%s", rname);
1320 	      else
1321 		(*info->fprintf_func) (info->stream, "%#x", value);
1322 	    }
1323 	}
1324 
1325       if (operand->flags & ARC_OPERAND_LIMM)
1326 	{
1327 	  arc_infop->operands[arc_infop->operands_count].kind
1328 	    = ARC_OPERAND_KIND_LIMM;
1329 	  /* It is not important to have exactly the LIMM indicator
1330 	     here.  */
1331 	  arc_infop->operands[arc_infop->operands_count].value = 63;
1332 	}
1333       else
1334 	{
1335 	  arc_infop->operands[arc_infop->operands_count].value = value;
1336 	  arc_infop->operands[arc_infop->operands_count].kind
1337 	    = (operand->flags & ARC_OPERAND_IR
1338 	       ? ARC_OPERAND_KIND_REG
1339 	       : ARC_OPERAND_KIND_SHIMM);
1340 	}
1341       arc_infop->operands_count ++;
1342     }
1343 
1344   /* Pretty print extra info for pc-relative operands.  */
1345   if (rpcl && rset)
1346     {
1347       if (info->flags & INSN_HAS_RELOC)
1348 	/* If the instruction has a reloc associated with it, then the
1349 	   offset field in the instruction will actually be the addend
1350 	   for the reloc.  (We are using REL type relocs).  In such
1351 	   cases, we can ignore the pc when computing addresses, since
1352 	   the addend is not currently pc-relative.  */
1353 	memaddr = 0;
1354 
1355       (*info->fprintf_func) (info->stream, "\t;");
1356       (*info->print_address_func) ((memaddr & ~3) + vpcl, info);
1357     }
1358 
1359   return insn_len;
1360 }
1361 
1362 
1363 disassembler_ftype
1364 arc_get_disassembler (bfd *abfd)
1365 {
1366   /* BFD my be absent, if opcodes is invoked from the debugger that
1367      has connected to remote target and doesn't have an ELF file.  */
1368   if (abfd != NULL)
1369     {
1370       /* Read the extension insns and registers, if any.  */
1371       build_ARC_extmap (abfd);
1372 #ifdef DEBUG
1373       dump_ARC_extmap ();
1374 #endif
1375     }
1376 
1377   return print_insn_arc;
1378 }
1379 
1380 void
1381 print_arc_disassembler_options (FILE *stream)
1382 {
1383   int i;
1384 
1385   fprintf (stream, _("\n\
1386 The following ARC specific disassembler options are supported for use \n\
1387 with -M switch (multiple options should be separated by commas):\n"));
1388 
1389   /* cpu=... options.  */
1390   for (i = 0; cpu_types[i].name; ++i)
1391     {
1392       /* As of now all value CPU values are less than 16 characters.  */
1393       fprintf (stream, "  cpu=%-16s\tEnforce %s ISA.\n",
1394 	       cpu_types[i].name, cpu_types[i].isa);
1395     }
1396 
1397   fprintf (stream, _("\
1398   dsp             Recognize DSP instructions.\n"));
1399   fprintf (stream, _("\
1400   spfp            Recognize FPX SP instructions.\n"));
1401   fprintf (stream, _("\
1402   dpfp            Recognize FPX DP instructions.\n"));
1403   fprintf (stream, _("\
1404   quarkse_em      Recognize FPU QuarkSE-EM instructions.\n"));
1405   fprintf (stream, _("\
1406   fpuda           Recognize double assist FPU instructions.\n"));
1407   fprintf (stream, _("\
1408   fpus            Recognize single precision FPU instructions.\n"));
1409   fprintf (stream, _("\
1410   fpud            Recognize double precision FPU instructions.\n"));
1411   fprintf (stream, _("\
1412   hex             Use only hexadecimal number to print immediates.\n"));
1413 }
1414 
1415 void arc_insn_decode (bfd_vma addr,
1416 		      struct disassemble_info *info,
1417 		      disassembler_ftype disasm_func,
1418 		      struct arc_instruction *insn)
1419 {
1420   const struct arc_opcode *opcode;
1421   struct arc_disassemble_info *arc_infop;
1422 
1423   /* Ensure that insn would be in the reset state.  */
1424   memset (insn, 0, sizeof (struct arc_instruction));
1425 
1426   /* There was an error when disassembling, for example memory read error.  */
1427   if (disasm_func (addr, info) < 0)
1428     {
1429       insn->valid = FALSE;
1430       return;
1431     }
1432 
1433   assert (info->private_data != NULL);
1434   arc_infop = info->private_data;
1435 
1436   insn->length  = arc_infop->insn_len;;
1437   insn->address = addr;
1438 
1439   /* Quick exit if memory at this address is not an instruction.  */
1440   if (info->insn_type == dis_noninsn)
1441     {
1442       insn->valid = FALSE;
1443       return;
1444     }
1445 
1446   insn->valid = TRUE;
1447 
1448   opcode = (const struct arc_opcode *) arc_infop->opcode;
1449   insn->insn_class = opcode->insn_class;
1450   insn->limm_value = arc_infop->limm;
1451   insn->limm_p     = arc_infop->limm_p;
1452 
1453   insn->is_control_flow = (info->insn_type == dis_branch
1454 			   || info->insn_type == dis_condbranch
1455 			   || info->insn_type == dis_jsr
1456 			   || info->insn_type == dis_condjsr);
1457 
1458   insn->has_delay_slot = info->branch_delay_insns;
1459   insn->writeback_mode
1460     = (enum arc_ldst_writeback_mode) arc_infop->writeback_mode;
1461   insn->data_size_mode = info->data_size;
1462   insn->condition_code = arc_infop->condition_code;
1463   memcpy (insn->operands, arc_infop->operands,
1464 	  sizeof (struct arc_insn_operand) * MAX_INSN_ARGS);
1465   insn->operands_count = arc_infop->operands_count;
1466 }
1467 
1468 /* Local variables:
1469    eval: (c-set-style "gnu")
1470    indent-tabs-mode: t
1471    End:  */
1472