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