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