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