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