[ARC] Force the disassam to use the hexadecimal number for printing
[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;
927   struct arc_operand_iterator iter;
928   struct arc_disassemble_info *arc_infop;
929
930   if (info->disassembler_options)
931     {
932       parse_disassembler_options (info->disassembler_options);
933
934       /* Avoid repeated parsing of the options.  */
935       info->disassembler_options = NULL;
936     }
937
938   if (info->private_data == NULL && !init_arc_disasm_info (info))
939     return -1;
940
941   memset (&iter, 0, sizeof (iter));
942   highbyte  = ((info->endian == BFD_ENDIAN_LITTLE) ? 1 : 0);
943   lowbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 0 : 1);
944
945   /* Figure out CPU type, unless it was enforced via disassembler options.  */
946   if (enforced_isa_mask == ARC_OPCODE_NONE)
947     {
948       Elf_Internal_Ehdr *header = NULL;
949
950       if (info->section && info->section->owner)
951         header = elf_elfheader (info->section->owner);
952
953       switch (info->mach)
954         {
955         case bfd_mach_arc_arc700:
956           isa_mask = ARC_OPCODE_ARC700;
957           break;
958
959         case bfd_mach_arc_arc600:
960           isa_mask = ARC_OPCODE_ARC600;
961           break;
962
963         case bfd_mach_arc_arcv2:
964         default:
965           isa_mask = ARC_OPCODE_ARCv2EM;
966           /* TODO: Perhaps remove definition of header since it is only used at
967              this location.  */
968           if (header != NULL
969               && (header->e_flags & EF_ARC_MACH_MSK) == EF_ARC_CPU_ARCV2HS)
970             isa_mask = ARC_OPCODE_ARCv2HS;
971           break;
972         }
973     }
974   else
975     isa_mask = enforced_isa_mask;
976
977   if (isa_mask == ARC_OPCODE_ARCv2HS)
978     {
979       /* FPU instructions are not extensions for HS.  */
980       add_to_decodelist (FLOAT, SP);
981       add_to_decodelist (FLOAT, DP);
982       add_to_decodelist (FLOAT, CVT);
983     }
984
985   /* This variable may be set by the instruction decoder.  It suggests
986      the number of bytes objdump should display on a single line.  If
987      the instruction decoder sets this, it should always set it to
988      the same value in order to get reasonable looking output.  */
989
990   info->bytes_per_line  = 8;
991
992   /* In the next lines, we set two info variables control the way
993      objdump displays the raw data.  For example, if bytes_per_line is
994      8 and bytes_per_chunk is 4, the output will look like this:
995      00:   00000000 00000000
996      with the chunks displayed according to "display_endian".  */
997
998   if (info->section
999       && !(info->section->flags & SEC_CODE))
1000     {
1001       /* This is not a CODE section.  */
1002       switch (info->section->size)
1003         {
1004         case 1:
1005         case 2:
1006         case 4:
1007           size = info->section->size;
1008           break;
1009         default:
1010           size = (info->section->size & 0x01) ? 1 : 4;
1011           break;
1012         }
1013       info->bytes_per_chunk = 1;
1014       info->display_endian = info->endian;
1015     }
1016   else
1017     {
1018       size = 2;
1019       info->bytes_per_chunk = 2;
1020       info->display_endian = info->endian;
1021     }
1022
1023   /* Read the insn into a host word.  */
1024   status = (*info->read_memory_func) (memaddr, buffer, size, info);
1025   if (status != 0)
1026     {
1027       (*info->memory_error_func) (status, memaddr, info);
1028       return -1;
1029     }
1030
1031   if (info->section
1032       && !(info->section->flags & SEC_CODE))
1033     {
1034       /* Data section.  */
1035       unsigned long data;
1036
1037       data = bfd_get_bits (buffer, size * 8,
1038                            info->display_endian == BFD_ENDIAN_BIG);
1039       switch (size)
1040         {
1041         case 1:
1042           (*info->fprintf_func) (info->stream, ".byte\t0x%02lx", data);
1043           break;
1044         case 2:
1045           (*info->fprintf_func) (info->stream, ".short\t0x%04lx", data);
1046           break;
1047         case 4:
1048           (*info->fprintf_func) (info->stream, ".word\t0x%08lx", data);
1049           break;
1050         default:
1051           abort ();
1052         }
1053       return size;
1054     }
1055
1056   insn_len = arc_insn_length (buffer[highbyte], buffer[lowbyte], info);
1057   pr_debug ("instruction length = %d bytes\n", insn_len);
1058   arc_infop = info->private_data;
1059   arc_infop->insn_len = insn_len;
1060
1061   switch (insn_len)
1062     {
1063     case 2:
1064       insn = (buffer[highbyte] << 8) | buffer[lowbyte];
1065       break;
1066
1067     case 4:
1068       {
1069         /* This is a long instruction: Read the remaning 2 bytes.  */
1070         status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 2, info);
1071         if (status != 0)
1072           {
1073             (*info->memory_error_func) (status, memaddr + 2, info);
1074             return -1;
1075           }
1076         insn = (unsigned long long) ARRANGE_ENDIAN (info, buffer);
1077       }
1078       break;
1079
1080     case 6:
1081       {
1082         status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 4, info);
1083         if (status != 0)
1084           {
1085             (*info->memory_error_func) (status, memaddr + 2, info);
1086             return -1;
1087           }
1088         insn = (unsigned long long) ARRANGE_ENDIAN (info, &buffer[2]);
1089         insn |= ((unsigned long long) buffer[highbyte] << 40)
1090           | ((unsigned long long) buffer[lowbyte] << 32);
1091       }
1092       break;
1093
1094     case 8:
1095       {
1096         status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 6, info);
1097         if (status != 0)
1098           {
1099             (*info->memory_error_func) (status, memaddr + 2, info);
1100             return -1;
1101           }
1102         insn =
1103           ((((unsigned long long) ARRANGE_ENDIAN (info, buffer)) << 32)
1104            | ((unsigned long long) ARRANGE_ENDIAN (info, &buffer[4])));
1105       }
1106       break;
1107
1108     default:
1109       /* There is no instruction whose length is not 2, 4, 6, or 8.  */
1110       abort ();
1111     }
1112
1113   pr_debug ("instruction value = %llx\n", insn);
1114
1115   /* Set some defaults for the insn info.  */
1116   info->insn_info_valid    = 1;
1117   info->branch_delay_insns = 0;
1118   info->data_size          = 4;
1119   info->insn_type          = dis_nonbranch;
1120   info->target             = 0;
1121   info->target2            = 0;
1122
1123   /* FIXME to be moved in dissasemble_init_for_target.  */
1124   info->disassembler_needs_relocs = TRUE;
1125
1126   /* Find the first match in the opcode table.  */
1127   if (!find_format (memaddr, insn, &insn_len, isa_mask, info, &opcode, &iter))
1128     return -1;
1129
1130   if (!opcode)
1131     {
1132       switch (insn_len)
1133         {
1134         case 2:
1135           (*info->fprintf_func) (info->stream, ".long %#04llx",
1136                                  insn & 0xffff);
1137           break;
1138         case 4:
1139           (*info->fprintf_func) (info->stream, ".long %#08llx",
1140                                  insn & 0xffffffff);
1141           break;
1142         case 6:
1143           (*info->fprintf_func) (info->stream, ".long %#08llx",
1144                                  insn & 0xffffffff);
1145           (*info->fprintf_func) (info->stream, ".long %#04llx",
1146                                  (insn >> 32) & 0xffff);
1147           break;
1148         case 8:
1149           (*info->fprintf_func) (info->stream, ".long %#08llx",
1150                                  insn & 0xffffffff);
1151           (*info->fprintf_func) (info->stream, ".long %#08llx",
1152                                  insn >> 32);
1153           break;
1154         default:
1155           abort ();
1156         }
1157
1158       info->insn_type = dis_noninsn;
1159       return insn_len;
1160     }
1161
1162   /* Print the mnemonic.  */
1163   (*info->fprintf_func) (info->stream, "%s", opcode->name);
1164
1165   /* Preselect the insn class.  */
1166   info->insn_type = arc_opcode_to_insn_type (opcode);
1167
1168   pr_debug ("%s: 0x%08llx\n", opcode->name, opcode->opcode);
1169
1170   print_flags (opcode, &insn, info);
1171
1172   if (opcode->operands[0] != 0)
1173     (*info->fprintf_func) (info->stream, "\t");
1174
1175   need_comma = FALSE;
1176   open_braket = FALSE;
1177   arc_infop->operands_count = 0;
1178
1179   /* Now extract and print the operands.  */
1180   operand = NULL;
1181   while (operand_iterator_next (&iter, &operand, &value))
1182     {
1183       if (open_braket && (operand->flags & ARC_OPERAND_BRAKET))
1184         {
1185           (*info->fprintf_func) (info->stream, "]");
1186           open_braket = FALSE;
1187           continue;
1188         }
1189
1190       /* Only take input from real operands.  */
1191       if (ARC_OPERAND_IS_FAKE (operand))
1192         continue;
1193
1194       if ((operand->flags & ARC_OPERAND_IGNORE)
1195           && (operand->flags & ARC_OPERAND_IR)
1196           && value == -1)
1197         continue;
1198
1199       if (operand->flags & ARC_OPERAND_COLON)
1200         {
1201           (*info->fprintf_func) (info->stream, ":");
1202           continue;
1203         }
1204
1205       if (need_comma)
1206         (*info->fprintf_func) (info->stream, ",");
1207
1208       if (!open_braket && (operand->flags & ARC_OPERAND_BRAKET))
1209         {
1210           (*info->fprintf_func) (info->stream, "[");
1211           open_braket = TRUE;
1212           need_comma = FALSE;
1213           continue;
1214         }
1215
1216       need_comma = TRUE;
1217
1218       /* Print the operand as directed by the flags.  */
1219       if (operand->flags & ARC_OPERAND_IR)
1220         {
1221           const char *rname;
1222
1223           assert (value >=0 && value < 64);
1224           rname = arcExtMap_coreRegName (value);
1225           if (!rname)
1226             rname = regnames[value];
1227           (*info->fprintf_func) (info->stream, "%s", rname);
1228           if (operand->flags & ARC_OPERAND_TRUNCATE)
1229             {
1230               rname = arcExtMap_coreRegName (value + 1);
1231               if (!rname)
1232                 rname = regnames[value + 1];
1233               (*info->fprintf_func) (info->stream, "%s", rname);
1234             }
1235         }
1236       else if (operand->flags & ARC_OPERAND_LIMM)
1237         {
1238           const char *rname = get_auxreg (opcode, value, isa_mask);
1239
1240           if (rname && open_braket)
1241             (*info->fprintf_func) (info->stream, "%s", rname);
1242           else
1243             {
1244               (*info->fprintf_func) (info->stream, "%#x", value);
1245               if (info->insn_type == dis_branch
1246                   || info->insn_type == dis_jsr)
1247                 info->target = (bfd_vma) value;
1248             }
1249         }
1250       else if (operand->flags & ARC_OPERAND_PCREL)
1251         {
1252            /* PCL relative.  */
1253           if (info->flags & INSN_HAS_RELOC)
1254             memaddr = 0;
1255           (*info->print_address_func) ((memaddr & ~3) + value, info);
1256
1257           info->target = (bfd_vma) (memaddr & ~3) + value;
1258         }
1259       else if (operand->flags & ARC_OPERAND_SIGNED)
1260         {
1261           const char *rname = get_auxreg (opcode, value, isa_mask);
1262           if (rname && open_braket)
1263             (*info->fprintf_func) (info->stream, "%s", rname);
1264           else
1265             {
1266               if (print_hex)
1267                 (*info->fprintf_func) (info->stream, "%#x", value);
1268               else
1269                 (*info->fprintf_func) (info->stream, "%d", value);
1270             }
1271         }
1272       else if (operand->flags & ARC_OPERAND_ADDRTYPE)
1273         {
1274           const char *addrtype = get_addrtype (value);
1275           (*info->fprintf_func) (info->stream, "%s", addrtype);
1276           /* A colon follow an address type.  */
1277           need_comma = FALSE;
1278         }
1279       else
1280         {
1281           if (operand->flags & ARC_OPERAND_TRUNCATE
1282               && !(operand->flags & ARC_OPERAND_ALIGNED32)
1283               && !(operand->flags & ARC_OPERAND_ALIGNED16)
1284               && value >= 0 && value <= 14)
1285             {
1286               switch (value)
1287                 {
1288                 case 0:
1289                   need_comma = FALSE;
1290                   break;
1291                 case 1:
1292                   (*info->fprintf_func) (info->stream, "r13");
1293                   break;
1294                 default:
1295                   (*info->fprintf_func) (info->stream, "r13-%s",
1296                                          regnames[13 + value - 1]);
1297                   break;
1298                 }
1299             }
1300           else
1301             {
1302               const char *rname = get_auxreg (opcode, value, isa_mask);
1303               if (rname && open_braket)
1304                 (*info->fprintf_func) (info->stream, "%s", rname);
1305               else
1306                 (*info->fprintf_func) (info->stream, "%#x", value);
1307             }
1308         }
1309
1310       if (operand->flags & ARC_OPERAND_LIMM)
1311         {
1312           arc_infop->operands[arc_infop->operands_count].kind
1313             = ARC_OPERAND_KIND_LIMM;
1314           /* It is not important to have exactly the LIMM indicator
1315              here.  */
1316           arc_infop->operands[arc_infop->operands_count].value = 63;
1317         }
1318       else
1319         {
1320           arc_infop->operands[arc_infop->operands_count].value = value;
1321           arc_infop->operands[arc_infop->operands_count].kind
1322             = (operand->flags & ARC_OPERAND_IR
1323                ? ARC_OPERAND_KIND_REG
1324                : ARC_OPERAND_KIND_SHIMM);
1325         }
1326       arc_infop->operands_count ++;
1327     }
1328
1329   return insn_len;
1330 }
1331
1332
1333 disassembler_ftype
1334 arc_get_disassembler (bfd *abfd)
1335 {
1336   /* BFD my be absent, if opcodes is invoked from the debugger that
1337      has connected to remote target and doesn't have an ELF file.  */
1338   if (abfd != NULL)
1339     {
1340       /* Read the extension insns and registers, if any.  */
1341       build_ARC_extmap (abfd);
1342 #ifdef DEBUG
1343       dump_ARC_extmap ();
1344 #endif
1345     }
1346
1347   return print_insn_arc;
1348 }
1349
1350 void
1351 print_arc_disassembler_options (FILE *stream)
1352 {
1353   int i;
1354
1355   fprintf (stream, _("\n\
1356 The following ARC specific disassembler options are supported for use \n\
1357 with -M switch (multiple options should be separated by commas):\n"));
1358
1359   /* cpu=... options.  */
1360   for (i = 0; cpu_types[i].name; ++i)
1361     {
1362       /* As of now all value CPU values are less than 16 characters.  */
1363       fprintf (stream, "  cpu=%-16s\tEnforce %s ISA.\n",
1364                cpu_types[i].name, cpu_types[i].isa);
1365     }
1366
1367   fprintf (stream, _("\
1368   dsp             Recognize DSP instructions.\n"));
1369   fprintf (stream, _("\
1370   spfp            Recognize FPX SP instructions.\n"));
1371   fprintf (stream, _("\
1372   dpfp            Recognize FPX DP instructions.\n"));
1373   fprintf (stream, _("\
1374   quarkse_em      Recognize FPU QuarkSE-EM instructions.\n"));
1375   fprintf (stream, _("\
1376   fpuda           Recognize double assist FPU instructions.\n"));
1377   fprintf (stream, _("\
1378   fpus            Recognize single precision FPU instructions.\n"));
1379   fprintf (stream, _("\
1380   fpud            Recognize double precision FPU instructions.\n"));
1381   fprintf (stream, _("\
1382   hex             Use only hexadecimal number to print immediates.\n"));
1383 }
1384
1385 void arc_insn_decode (bfd_vma addr,
1386                       struct disassemble_info *info,
1387                       disassembler_ftype disasm_func,
1388                       struct arc_instruction *insn)
1389 {
1390   const struct arc_opcode *opcode;
1391   struct arc_disassemble_info *arc_infop;
1392
1393   /* Ensure that insn would be in the reset state.  */
1394   memset (insn, 0, sizeof (struct arc_instruction));
1395
1396   /* There was an error when disassembling, for example memory read error.  */
1397   if (disasm_func (addr, info) < 0)
1398     {
1399       insn->valid = FALSE;
1400       return;
1401     }
1402
1403   assert (info->private_data != NULL);
1404   arc_infop = info->private_data;
1405
1406   insn->length  = arc_infop->insn_len;;
1407   insn->address = addr;
1408
1409   /* Quick exit if memory at this address is not an instruction.  */
1410   if (info->insn_type == dis_noninsn)
1411     {
1412       insn->valid = FALSE;
1413       return;
1414     }
1415
1416   insn->valid = TRUE;
1417
1418   opcode = (const struct arc_opcode *) arc_infop->opcode;
1419   insn->insn_class = opcode->insn_class;
1420   insn->limm_value = arc_infop->limm;
1421   insn->limm_p     = arc_infop->limm_p;
1422
1423   insn->is_control_flow = (info->insn_type == dis_branch
1424                            || info->insn_type == dis_condbranch
1425                            || info->insn_type == dis_jsr
1426                            || info->insn_type == dis_condjsr);
1427
1428   insn->has_delay_slot = info->branch_delay_insns;
1429   insn->writeback_mode
1430     = (enum arc_ldst_writeback_mode) arc_infop->writeback_mode;
1431   insn->data_size_mode = info->data_size;
1432   insn->condition_code = arc_infop->condition_code;
1433   memcpy (insn->operands, arc_infop->operands,
1434           sizeof (struct arc_insn_operand) * MAX_INSN_ARGS);
1435   insn->operands_count = arc_infop->operands_count;
1436 }
1437
1438 /* Local variables:
1439    eval: (c-set-style "gnu")
1440    indent-tabs-mode: t
1441    End:  */