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