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