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