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