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