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