Stop the ARC disassembler from seg-faulting if initialised without a BFD present.
[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;
481
482   /* First, try the extension instructions.  */
483   einsn = arcExtMap_insn (OPCODE (insn[0]), insn[0]);
484   if (einsn != NULL)
485     {
486       const char *errmsg = NULL;
487
488       opcode = arcExtMap_genOpcode (einsn, 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     case bfd_mach_arc_arc600:
707       return (major_opcode > 0xb) ? 2 : 4;
708       break;
709
710     case bfd_mach_arc_arcv2:
711       return (major_opcode > 0x7) ? 2 : 4;
712       break;
713
714     default:
715       abort ();
716     }
717 }
718
719 /* Extract and return the value of OPERAND from the instruction whose value
720    is held in the array INSN.  */
721
722 static int
723 extract_operand_value (const struct arc_operand *operand, unsigned *insn)
724 {
725   int value;
726
727   /* Read the limm operand, if required.  */
728   if (operand->flags & ARC_OPERAND_LIMM)
729     /* The second part of the instruction value will have been loaded as
730        part of the find_format call made earlier.  */
731     value = insn[1];
732   else
733     {
734       if (operand->extract)
735         value = (*operand->extract) (insn[0], (int *) NULL);
736       else
737         {
738           if (operand->flags & ARC_OPERAND_ALIGNED32)
739             {
740               value = (insn[0] >> operand->shift)
741                 & ((1 << (operand->bits - 2)) - 1);
742               value = value << 2;
743             }
744           else
745             {
746               value = (insn[0] >> operand->shift) & ((1 << operand->bits) - 1);
747             }
748           if (operand->flags & ARC_OPERAND_SIGNED)
749             {
750               int signbit = 1 << (operand->bits - 1);
751               value = (value ^ signbit) - signbit;
752             }
753         }
754     }
755
756   return value;
757 }
758
759 /* Find the next operand, and the operands value from ITER.  Return TRUE if
760    there is another operand, otherwise return FALSE.  If there is an
761    operand returned then the operand is placed into OPERAND, and the value
762    into VALUE.  If there is no operand returned then OPERAND and VALUE are
763    unchanged.  */
764
765 static bfd_boolean
766 operand_iterator_next (struct arc_operand_iterator *iter,
767                        const struct arc_operand **operand,
768                        int *value)
769 {
770   if (iter->mode == OPERAND_ITERATOR_STANDARD)
771     {
772       if (*iter->state.standard.opidx == 0)
773         {
774           *operand = NULL;
775           return FALSE;
776         }
777
778       *operand = &arc_operands[*iter->state.standard.opidx];
779       *value = extract_operand_value (*operand, iter->insn);
780       iter->state.standard.opidx++;
781     }
782   else
783     {
784       const struct arc_operand *operand_base, *operand_limm;
785       int value_base, value_limm;
786
787       if (*iter->state.long_insn.opidx_limm == 0)
788         {
789           *operand = NULL;
790           return FALSE;
791         }
792
793       operand_base = &arc_operands[*iter->state.long_insn.opidx_base];
794       operand_limm = &arc_operands[*iter->state.long_insn.opidx_limm];
795
796       if (operand_base->flags & ARC_OPERAND_LIMM)
797         {
798           /* We've reached the end of the operand list.  */
799           *operand = NULL;
800           return FALSE;
801         }
802
803       value_base = value_limm = 0;
804       if (!(operand_limm->flags & ARC_OPERAND_IGNORE))
805         {
806           /* This should never happen.  If it does then the use of
807              extract_operand_value below will access memory beyond
808              the insn array.  */
809           assert ((operand_limm->flags & ARC_OPERAND_LIMM) == 0);
810
811           *operand = operand_limm;
812           value_limm = extract_operand_value (*operand, &iter->insn[1]);
813         }
814
815       if (!(operand_base->flags & ARC_OPERAND_IGNORE))
816         {
817           *operand = operand_base;
818           value_base = extract_operand_value (*operand, iter->insn);
819         }
820
821       /* This is a bit of a fudge.  There's no reason why simply ORing
822          together the two values is the right thing to do, however, for all
823          the cases we currently have, it is the right thing, so, for now,
824          I've put off solving the more complex problem.  */
825       *value = value_base | value_limm;
826
827       iter->state.long_insn.opidx_base++;
828       iter->state.long_insn.opidx_limm++;
829     }
830   return TRUE;
831 }
832
833 /* Helper for parsing the options.  */
834
835 static void
836 parse_option (char *option)
837 {
838   if (CONST_STRNEQ (option, "dsp"))
839     add_to_decodelist (DSP, NONE);
840
841   else if (CONST_STRNEQ (option, "spfp"))
842     add_to_decodelist (FLOAT, SPX);
843
844   else if (CONST_STRNEQ (option, "dpfp"))
845     add_to_decodelist (FLOAT, DPX);
846
847   else if (CONST_STRNEQ (option, "quarkse_em"))
848     add_to_decodelist (FLOAT, QUARKSE);
849
850   else if (CONST_STRNEQ (option, "fpuda"))
851     add_to_decodelist (FLOAT, DPA);
852
853   else if (CONST_STRNEQ (option, "fpud"))
854     {
855       add_to_decodelist (FLOAT, SP);
856       add_to_decodelist (FLOAT, CVT);
857     }
858
859   else if (CONST_STRNEQ (option, "fpus"))
860     {
861       add_to_decodelist (FLOAT, DP);
862       add_to_decodelist (FLOAT, CVT);
863     }
864   else
865     fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
866 }
867
868 /* Go over the options list and parse it.  */
869
870 static void
871 parse_disassembler_options (char *options)
872 {
873   if (options == NULL)
874     return;
875
876   while (*options)
877     {
878       /* Skip empty options.  */
879       if (*options == ',')
880         {
881           ++ options;
882           continue;
883         }
884
885       parse_option (options);
886
887       while (*options != ',' && *options != '\0')
888         ++ options;
889     }
890 }
891
892 /* Disassemble ARC instructions.  */
893
894 static int
895 print_insn_arc (bfd_vma memaddr,
896                 struct disassemble_info *info)
897 {
898   bfd_byte buffer[4];
899   unsigned int lowbyte, highbyte;
900   int status;
901   unsigned int insn_len;
902   unsigned insn[2] = { 0, 0 };
903   unsigned isa_mask;
904   const struct arc_opcode *opcode;
905   bfd_boolean need_comma;
906   bfd_boolean open_braket;
907   int size;
908   const struct arc_operand *operand;
909   int value;
910   struct arc_operand_iterator iter;
911   Elf_Internal_Ehdr *header = NULL;
912
913   if (info->disassembler_options)
914     {
915       parse_disassembler_options (info->disassembler_options);
916
917       /* Avoid repeated parsing of the options.  */
918       info->disassembler_options = NULL;
919     }
920
921   memset (&iter, 0, sizeof (iter));
922   lowbyte  = ((info->endian == BFD_ENDIAN_LITTLE) ? 1 : 0);
923   highbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 0 : 1);
924
925   if (info->section && info->section->owner)
926     header = elf_elfheader (info->section->owner);
927
928   switch (info->mach)
929     {
930     case bfd_mach_arc_arc700:
931       isa_mask = ARC_OPCODE_ARC700;
932       break;
933
934     case bfd_mach_arc_arc600:
935       isa_mask = ARC_OPCODE_ARC600;
936       break;
937
938     case bfd_mach_arc_arcv2:
939     default:
940       isa_mask = ARC_OPCODE_ARCv2EM;
941       /* TODO: Perhaps remove defitinion of header since it is only used at
942          this location.  */
943       if (header != NULL
944           && (header->e_flags & EF_ARC_MACH_MSK) == EF_ARC_CPU_ARCV2HS)
945         {
946           isa_mask = ARC_OPCODE_ARCv2HS;
947           /* FPU instructions are not extensions for HS.  */
948           add_to_decodelist (FLOAT, SP);
949           add_to_decodelist (FLOAT, DP);
950           add_to_decodelist (FLOAT, CVT);
951         }
952       break;
953     }
954
955   /* This variable may be set by the instruction decoder.  It suggests
956      the number of bytes objdump should display on a single line.  If
957      the instruction decoder sets this, it should always set it to
958      the same value in order to get reasonable looking output.  */
959
960   info->bytes_per_line  = 8;
961
962   /* In the next lines, we set two info variables control the way
963      objdump displays the raw data.  For example, if bytes_per_line is
964      8 and bytes_per_chunk is 4, the output will look like this:
965      00:   00000000 00000000
966      with the chunks displayed according to "display_endian".  */
967
968   if (info->section
969       && !(info->section->flags & SEC_CODE))
970     {
971       /* This is not a CODE section.  */
972       switch (info->section->size)
973         {
974         case 1:
975         case 2:
976         case 4:
977           size = info->section->size;
978           break;
979         default:
980           size = (info->section->size & 0x01) ? 1 : 4;
981           break;
982         }
983       info->bytes_per_chunk = 1;
984       info->display_endian = info->endian;
985     }
986   else
987     {
988       size = 2;
989       info->bytes_per_chunk = 2;
990       info->display_endian = info->endian;
991     }
992
993   /* Read the insn into a host word.  */
994   status = (*info->read_memory_func) (memaddr, buffer, size, info);
995   if (status != 0)
996     {
997       (*info->memory_error_func) (status, memaddr, info);
998       return -1;
999     }
1000
1001   if (info->section
1002       && !(info->section->flags & SEC_CODE))
1003     {
1004       /* Data section.  */
1005       unsigned long data;
1006
1007       data = bfd_get_bits (buffer, size * 8,
1008                            info->display_endian == BFD_ENDIAN_BIG);
1009       switch (size)
1010         {
1011         case 1:
1012           (*info->fprintf_func) (info->stream, ".byte\t0x%02lx", data);
1013           break;
1014         case 2:
1015           (*info->fprintf_func) (info->stream, ".short\t0x%04lx", data);
1016           break;
1017         case 4:
1018           (*info->fprintf_func) (info->stream, ".word\t0x%08lx", data);
1019           break;
1020         default:
1021           abort ();
1022         }
1023       return size;
1024     }
1025
1026   insn_len = arc_insn_length (buffer[lowbyte], buffer[highbyte], info);
1027   pr_debug ("instruction length = %d bytes\n", insn_len);
1028
1029   switch (insn_len)
1030     {
1031     case 2:
1032       insn[0] = (buffer[lowbyte] << 8) | buffer[highbyte];
1033       break;
1034
1035     default:
1036       /* An unknown instruction is treated as being length 4.  This is
1037          possibly not the best solution, but matches the behaviour that was
1038          in place before the table based instruction length look-up was
1039          introduced.  */
1040     case 4:
1041       /* This is a long instruction: Read the remaning 2 bytes.  */
1042       status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 2, info);
1043       if (status != 0)
1044         {
1045           (*info->memory_error_func) (status, memaddr + 2, info);
1046           return -1;
1047         }
1048       insn[0] = ARRANGE_ENDIAN (info, buffer);
1049       break;
1050     }
1051
1052   /* Set some defaults for the insn info.  */
1053   info->insn_info_valid    = 1;
1054   info->branch_delay_insns = 0;
1055   info->data_size          = 0;
1056   info->insn_type          = dis_nonbranch;
1057   info->target             = 0;
1058   info->target2            = 0;
1059
1060   /* FIXME to be moved in dissasemble_init_for_target.  */
1061   info->disassembler_needs_relocs = TRUE;
1062
1063   /* Find the first match in the opcode table.  */
1064   if (!find_format (memaddr, insn, &insn_len, isa_mask, info, &opcode, &iter))
1065     return -1;
1066
1067   if (!opcode)
1068     {
1069       if (insn_len == 2)
1070         (*info->fprintf_func) (info->stream, ".long %#04x", insn[0]);
1071       else
1072         (*info->fprintf_func) (info->stream, ".long %#08x", insn[0]);
1073
1074       info->insn_type = dis_noninsn;
1075       return insn_len;
1076     }
1077
1078   /* Print the mnemonic.  */
1079   (*info->fprintf_func) (info->stream, "%s", opcode->name);
1080
1081   /* Preselect the insn class.  */
1082   switch (opcode->insn_class)
1083     {
1084     case BRANCH:
1085     case JUMP:
1086       if (!strncmp (opcode->name, "bl", 2)
1087           || !strncmp (opcode->name, "jl", 2))
1088         {
1089           if (opcode->subclass == COND)
1090             info->insn_type = dis_condjsr;
1091           else
1092             info->insn_type = dis_jsr;
1093         }
1094       else
1095         {
1096           if (opcode->subclass == COND)
1097             info->insn_type = dis_condbranch;
1098           else
1099             info->insn_type = dis_branch;
1100         }
1101       break;
1102     case MEMORY:
1103       info->insn_type = dis_dref; /* FIXME! DB indicates mov as memory! */
1104       break;
1105     default:
1106       info->insn_type = dis_nonbranch;
1107       break;
1108     }
1109
1110   pr_debug ("%s: 0x%08x\n", opcode->name, opcode->opcode);
1111
1112   print_flags (opcode, insn, info);
1113
1114   if (opcode->operands[0] != 0)
1115     (*info->fprintf_func) (info->stream, "\t");
1116
1117   need_comma = FALSE;
1118   open_braket = FALSE;
1119
1120   /* Now extract and print the operands.  */
1121   operand = NULL;
1122   while (operand_iterator_next (&iter, &operand, &value))
1123     {
1124       if (open_braket && (operand->flags & ARC_OPERAND_BRAKET))
1125         {
1126           (*info->fprintf_func) (info->stream, "]");
1127           open_braket = FALSE;
1128           continue;
1129         }
1130
1131       /* Only take input from real operands.  */
1132       if (ARC_OPERAND_IS_FAKE (operand))
1133         continue;
1134
1135       if ((operand->flags & ARC_OPERAND_IGNORE)
1136           && (operand->flags & ARC_OPERAND_IR)
1137           && value == -1)
1138         continue;
1139
1140       if (operand->flags & ARC_OPERAND_COLON)
1141         {
1142           (*info->fprintf_func) (info->stream, ":");
1143           continue;
1144         }
1145
1146       if (need_comma)
1147         (*info->fprintf_func) (info->stream, ",");
1148
1149       if (!open_braket && (operand->flags & ARC_OPERAND_BRAKET))
1150         {
1151           (*info->fprintf_func) (info->stream, "[");
1152           open_braket = TRUE;
1153           need_comma = FALSE;
1154           continue;
1155         }
1156
1157       need_comma = TRUE;
1158
1159       /* Print the operand as directed by the flags.  */
1160       if (operand->flags & ARC_OPERAND_IR)
1161         {
1162           const char *rname;
1163
1164           assert (value >=0 && value < 64);
1165           rname = arcExtMap_coreRegName (value);
1166           if (!rname)
1167             rname = regnames[value];
1168           (*info->fprintf_func) (info->stream, "%s", rname);
1169           if (operand->flags & ARC_OPERAND_TRUNCATE)
1170             {
1171               rname = arcExtMap_coreRegName (value + 1);
1172               if (!rname)
1173                 rname = regnames[value + 1];
1174               (*info->fprintf_func) (info->stream, "%s", rname);
1175             }
1176         }
1177       else if (operand->flags & ARC_OPERAND_LIMM)
1178         {
1179           const char *rname = get_auxreg (opcode, value, isa_mask);
1180
1181           if (rname && open_braket)
1182             (*info->fprintf_func) (info->stream, "%s", rname);
1183           else
1184             {
1185               (*info->fprintf_func) (info->stream, "%#x", value);
1186               if (info->insn_type == dis_branch
1187                   || info->insn_type == dis_jsr)
1188                 info->target = (bfd_vma) value;
1189             }
1190         }
1191       else if (operand->flags & ARC_OPERAND_PCREL)
1192         {
1193            /* PCL relative.  */
1194           if (info->flags & INSN_HAS_RELOC)
1195             memaddr = 0;
1196           (*info->print_address_func) ((memaddr & ~3) + value, info);
1197
1198           info->target = (bfd_vma) (memaddr & ~3) + value;
1199         }
1200       else if (operand->flags & ARC_OPERAND_SIGNED)
1201         {
1202           const char *rname = get_auxreg (opcode, value, isa_mask);
1203           if (rname && open_braket)
1204             (*info->fprintf_func) (info->stream, "%s", rname);
1205           else
1206             (*info->fprintf_func) (info->stream, "%d", value);
1207         }
1208       else if (operand->flags & ARC_OPERAND_ADDRTYPE)
1209         {
1210           const char *addrtype = get_addrtype (value);
1211           (*info->fprintf_func) (info->stream, "%s", addrtype);
1212           /* A colon follow an address type.  */
1213           need_comma = FALSE;
1214         }
1215       else
1216         {
1217           if (operand->flags & ARC_OPERAND_TRUNCATE
1218               && !(operand->flags & ARC_OPERAND_ALIGNED32)
1219               && !(operand->flags & ARC_OPERAND_ALIGNED16)
1220               && value > 0 && value <= 14)
1221             (*info->fprintf_func) (info->stream, "r13-%s",
1222                                    regnames[13 + value - 1]);
1223           else
1224             {
1225               const char *rname = get_auxreg (opcode, value, isa_mask);
1226               if (rname && open_braket)
1227                 (*info->fprintf_func) (info->stream, "%s", rname);
1228               else
1229                 (*info->fprintf_func) (info->stream, "%#x", value);
1230             }
1231         }
1232     }
1233
1234   return insn_len;
1235 }
1236
1237
1238 disassembler_ftype
1239 arc_get_disassembler (bfd *abfd)
1240 {
1241   /* BFD my be absent, if opcodes is invoked from the debugger that
1242      has connected to remote target and doesn't have an ELF file.  */
1243   if (abfd != NULL)
1244     {
1245       /* Read the extension insns and registers, if any.  */
1246       build_ARC_extmap (abfd);
1247 #ifdef DEBUG
1248       dump_ARC_extmap ();
1249 #endif
1250     }
1251
1252   return print_insn_arc;
1253 }
1254
1255 /* Disassemble ARC instructions.  Used by debugger.  */
1256
1257 struct arcDisState
1258 arcAnalyzeInstr (bfd_vma memaddr,
1259                  struct disassemble_info *info)
1260 {
1261   struct arcDisState ret;
1262   memset (&ret, 0, sizeof (struct arcDisState));
1263
1264   ret.instructionLen = print_insn_arc (memaddr, info);
1265
1266 #if 0
1267   ret.words[0] = insn[0];
1268   ret.words[1] = insn[1];
1269   ret._this = &ret;
1270   ret.coreRegName = _coreRegName;
1271   ret.auxRegName = _auxRegName;
1272   ret.condCodeName = _condCodeName;
1273   ret.instName = _instName;
1274 #endif
1275
1276   return ret;
1277 }
1278
1279 void
1280 print_arc_disassembler_options (FILE *stream)
1281 {
1282   fprintf (stream, _("\n\
1283 The following ARC specific disassembler options are supported for use \n\
1284 with -M switch (multiple options should be separated by commas):\n"));
1285
1286   fprintf (stream, _("\
1287   dsp             Recognize DSP instructions.\n"));
1288   fprintf (stream, _("\
1289   spfp            Recognize FPX SP instructions.\n"));
1290   fprintf (stream, _("\
1291   dpfp            Recognize FPX DP instructions.\n"));
1292   fprintf (stream, _("\
1293   quarkse_em      Recognize FPU QuarkSE-EM instructions.\n"));
1294   fprintf (stream, _("\
1295   fpuda           Recognize double assist FPU instructions.\n"));
1296   fprintf (stream, _("\
1297   fpus            Recognize single precision FPU instructions.\n"));
1298   fprintf (stream, _("\
1299   fpud            Recognize double precision FPU instructions.\n"));
1300 }
1301
1302
1303 /* Local variables:
1304    eval: (c-set-style "gnu")
1305    indent-tabs-mode: t
1306    End:  */