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