Home | History | Annotate | Download | only in opcodes
      1 /* Instruction printing code for the ARC.
      2    Copyright (C) 1994-2016 Free Software Foundation, Inc.
      3 
      4    Contributed by Claudiu Zissulescu (claziss (at) 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 "arc-dis.h"
     29 #include "arc-ext.h"
     30 
     31 /* Structure used to iterate over, and extract the values for, operands of
     32    an opcode.  */
     33 
     34 struct arc_operand_iterator
     35 {
     36   enum
     37     {
     38       OPERAND_ITERATOR_STANDARD,
     39       OPERAND_ITERATOR_LONG
     40     } mode;
     41 
     42   /* The array of 32-bit values that make up this instruction.  All
     43      required values have been pre-loaded into this array during the
     44      find_format call.  */
     45   unsigned *insn;
     46 
     47   union
     48   {
     49     struct
     50     {
     51       /* The opcode this iterator is operating on.  */
     52       const struct arc_opcode *opcode;
     53 
     54       /* The index into the opcodes operand index list.  */
     55       const unsigned char *opidx;
     56     } standard;
     57 
     58     struct
     59     {
     60       /* The long instruction opcode this iterator is operating on.  */
     61       const struct arc_long_opcode *long_opcode;
     62 
     63       /* Two indexes into the opcodes operand index lists.  */
     64       const unsigned char *opidx_base, *opidx_limm;
     65     } long_insn;
     66   } state;
     67 };
     68 
     69 /* Globals variables.  */
     70 
     71 static const char * const regnames[64] =
     72 {
     73   "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
     74   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
     75   "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
     76   "r24", "r25", "gp", "fp", "sp", "ilink", "r30", "blink",
     77 
     78   "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
     79   "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
     80   "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",
     81   "r56", "r57", "ACCL", "ACCH", "lp_count", "rezerved", "LIMM", "pcl"
     82 };
     83 
     84 /* Macros section.  */
     85 
     86 #ifdef DEBUG
     87 # define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args)
     88 #else
     89 # define pr_debug(fmt, args...)
     90 #endif
     91 
     92 #define ARRANGE_ENDIAN(info, buf)					\
     93   (info->endian == BFD_ENDIAN_LITTLE ? bfd_getm32 (bfd_getl32 (buf))	\
     94    : bfd_getb32 (buf))
     95 
     96 #define BITS(word,s,e)  (((word) << (sizeof (word) * 8 - 1 - e)) >>	\
     97 			 (s + (sizeof (word) * 8 - 1 - e)))
     98 #define OPCODE(word)	(BITS ((word), 27, 31))
     99 
    100 #define OPCODE_AC(word)   (BITS ((word), 11, 15))
    101 
    102 /* Functions implementation.  */
    103 
    104 static bfd_vma
    105 bfd_getm32 (unsigned int data)
    106 {
    107   bfd_vma value = 0;
    108 
    109   value = ((data & 0xff00) | (data & 0xff)) << 16;
    110   value |= ((data & 0xff0000) | (data & 0xff000000)) >> 16;
    111   return value;
    112 }
    113 
    114 static int
    115 special_flag_p (const char *opname,
    116 		const char *flgname)
    117 {
    118   const struct arc_flag_special *flg_spec;
    119   unsigned i, j, flgidx;
    120 
    121   for (i = 0; i < arc_num_flag_special; i++)
    122     {
    123       flg_spec = &arc_flag_special_cases[i];
    124 
    125       if (strcmp (opname, flg_spec->name))
    126 	continue;
    127 
    128       /* Found potential special case instruction.  */
    129       for (j=0;; ++j)
    130 	{
    131 	  flgidx = flg_spec->flags[j];
    132 	  if (flgidx == 0)
    133 	    break; /* End of the array.  */
    134 
    135 	  if (strcmp (flgname, arc_flag_operands[flgidx].name) == 0)
    136 	    return 1;
    137 	}
    138     }
    139   return 0;
    140 }
    141 
    142 /* Find opcode from ARC_TABLE given the instruction described by INSN and
    143    INSNLEN.  The ISA_MASK restricts the possible matches in ARC_TABLE.  */
    144 
    145 static const struct arc_opcode *
    146 find_format_from_table (const struct arc_opcode *arc_table,
    147                         unsigned *insn, unsigned int insn_len,
    148                         unsigned isa_mask, bfd_boolean *has_limm)
    149 {
    150   unsigned int i = 0;
    151   const struct arc_opcode *opcode = NULL;
    152   const unsigned char *opidx;
    153   const unsigned char *flgidx;
    154 
    155   do {
    156     bfd_boolean invalid = FALSE;
    157 
    158     opcode = &arc_table[i++];
    159 
    160     if (ARC_SHORT (opcode->mask) && (insn_len == 2))
    161       {
    162 	if (OPCODE_AC (opcode->opcode) != OPCODE_AC (insn[0]))
    163 	  continue;
    164       }
    165     else if (!ARC_SHORT (opcode->mask) && (insn_len == 4))
    166       {
    167 	if (OPCODE (opcode->opcode) != OPCODE (insn[0]))
    168 	  continue;
    169       }
    170     else
    171       continue;
    172 
    173     if ((insn[0] ^ opcode->opcode) & opcode->mask)
    174       continue;
    175 
    176     if (!(opcode->cpu & isa_mask))
    177       continue;
    178 
    179     *has_limm = FALSE;
    180 
    181     /* Possible candidate, check the operands.  */
    182     for (opidx = opcode->operands; *opidx; opidx++)
    183       {
    184 	int value;
    185 	const struct arc_operand *operand = &arc_operands[*opidx];
    186 
    187 	if (operand->flags & ARC_OPERAND_FAKE)
    188 	  continue;
    189 
    190 	if (operand->extract)
    191 	  value = (*operand->extract) (insn[0], &invalid);
    192 	else
    193 	  value = (insn[0] >> operand->shift) & ((1 << operand->bits) - 1);
    194 
    195 	/* Check for LIMM indicator.  If it is there, then make sure
    196 	   we pick the right format.  */
    197 	if (operand->flags & ARC_OPERAND_IR
    198 	    && !(operand->flags & ARC_OPERAND_LIMM))
    199 	  {
    200 	    if ((value == 0x3E && insn_len == 4)
    201 		|| (value == 0x1E && insn_len == 2))
    202 	      {
    203 		invalid = TRUE;
    204 		break;
    205 	      }
    206 	  }
    207 
    208         if (operand->flags & ARC_OPERAND_LIMM
    209             && !(operand->flags & ARC_OPERAND_DUPLICATE))
    210           *has_limm = TRUE;
    211       }
    212 
    213     /* Check the flags.  */
    214     for (flgidx = opcode->flags; *flgidx; flgidx++)
    215       {
    216 	/* Get a valid flag class.  */
    217 	const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
    218 	const unsigned *flgopridx;
    219 	int foundA = 0, foundB = 0;
    220 	unsigned int value;
    221 
    222 	/* Check first the extensions.  */
    223 	if (cl_flags->flag_class & F_CLASS_EXTEND)
    224 	  {
    225 	    value = (insn[0] & 0x1F);
    226 	    if (arcExtMap_condCodeName (value))
    227 	      continue;
    228 	  }
    229 	for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
    230 	  {
    231 	    const struct arc_flag_operand *flg_operand =
    232 	      &arc_flag_operands[*flgopridx];
    233 
    234 	    value = (insn[0] >> flg_operand->shift)
    235 	      & ((1 << flg_operand->bits) - 1);
    236 	    if (value == flg_operand->code)
    237 	      foundA = 1;
    238 	    if (value)
    239 	      foundB = 1;
    240 	  }
    241 	if (!foundA && foundB)
    242 	  {
    243 	    invalid = TRUE;
    244 	    break;
    245 	  }
    246       }
    247 
    248     if (invalid)
    249       continue;
    250 
    251     /* The instruction is valid.  */
    252     return opcode;
    253   } while (opcode->mask);
    254 
    255   return NULL;
    256 }
    257 
    258 /* Find long instructions matching values in INSN array.  */
    259 
    260 static const struct arc_long_opcode *
    261 find_format_long_instructions (unsigned *insn,
    262                                unsigned int *insn_len,
    263                                unsigned isa_mask,
    264                                bfd_vma memaddr,
    265                                struct disassemble_info *info)
    266 {
    267   unsigned int i;
    268   unsigned limm = 0;
    269   bfd_boolean limm_loaded = FALSE;
    270 
    271   for (i = 0; i < arc_num_long_opcodes; ++i)
    272     {
    273       bfd_byte buffer[4];
    274       int status;
    275       const struct arc_opcode *opcode;
    276 
    277       opcode = &arc_long_opcodes[i].base_opcode;
    278 
    279       if (ARC_SHORT (opcode->mask) && (*insn_len == 2))
    280         {
    281           if (OPCODE_AC (opcode->opcode) != OPCODE_AC (insn[0]))
    282             continue;
    283         }
    284       else if (!ARC_SHORT (opcode->mask) && (*insn_len == 4))
    285         {
    286           if (OPCODE (opcode->opcode) != OPCODE (insn[0]))
    287             continue;
    288         }
    289       else
    290         continue;
    291 
    292       if ((insn[0] ^ opcode->opcode) & opcode->mask)
    293         continue;
    294 
    295       if (!(opcode->cpu & isa_mask))
    296         continue;
    297 
    298       if (!limm_loaded)
    299         {
    300           status = (*info->read_memory_func) (memaddr + *insn_len, buffer,
    301                                               4, info);
    302           if (status != 0)
    303             return NULL;
    304 
    305           limm = ARRANGE_ENDIAN (info, buffer);
    306           limm_loaded = TRUE;
    307         }
    308 
    309       /* Check the second word using the mask and template.  */
    310       if ((limm & arc_long_opcodes[i].limm_mask)
    311           != arc_long_opcodes[i].limm_template)
    312         continue;
    313 
    314       (*insn_len) += 4;
    315       insn[1] = limm;
    316       return &arc_long_opcodes[i];
    317     }
    318 
    319   return NULL;
    320 }
    321 
    322 /* Find opcode for INSN, trying various different sources.  The instruction
    323    length in INSN_LEN will be updated if the instruction requires a LIMM
    324    extension, and the additional values loaded into the INSN array (which
    325    must be big enough).
    326 
    327    A pointer to the opcode is placed into OPCODE_RESULT, and ITER is
    328    initialised, ready to iterate over the operands of the found opcode.
    329 
    330    This function returns TRUE in almost all cases, FALSE is reserved to
    331    indicate an error (failing to find an opcode is not an error) a
    332    returned result of FALSE would indicate that the disassembler can't
    333    continue.
    334 
    335    If no matching opcode is found then the returned result will be TRUE,
    336    the value placed into OPCODE_RESULT will be NULL, ITER will be
    337    undefined, and INSN_LEN will be unchanged.
    338 
    339    If a matching opcode is found, then the returned result will be TRUE,
    340    the opcode pointer is placed into OPCODE_RESULT, INSN_LEN will be
    341    increased by 4 if the instruction requires a LIMM, and the LIMM value
    342    will have been loaded into the INSN[1].  Finally, ITER will have been
    343    initialised so that calls to OPERAND_ITERATOR_NEXT will iterate over
    344    the opcode's operands.  */
    345 
    346 static bfd_boolean
    347 find_format (bfd_vma memaddr, unsigned *insn, unsigned int *insn_len,
    348              unsigned isa_mask, struct disassemble_info *info,
    349              const struct arc_opcode **opcode_result,
    350              struct arc_operand_iterator *iter)
    351 {
    352   const struct arc_opcode *opcode;
    353   bfd_boolean needs_limm;
    354 
    355   /* Find the first match in the opcode table.  */
    356   opcode = find_format_from_table (arc_opcodes, insn, *insn_len,
    357                                    isa_mask, &needs_limm);
    358 
    359   if (opcode == NULL)
    360     {
    361       const extInstruction_t *einsn;
    362 
    363       /* No instruction found.  Try the extensions.  */
    364       einsn = arcExtMap_insn (OPCODE (insn[0]), insn[0]);
    365       if (einsn != NULL)
    366 	{
    367 	  const char *errmsg = NULL;
    368 	  opcode = arcExtMap_genOpcode (einsn, isa_mask, &errmsg);
    369 	  if (opcode == NULL)
    370 	    {
    371 	      (*info->fprintf_func) (info->stream,
    372 				     "An error occured while "
    373 				     "generating the extension instruction "
    374 				     "operations");
    375               *opcode_result = NULL;
    376 	      return FALSE;
    377 	    }
    378 
    379 	  opcode = find_format_from_table (opcode, insn, *insn_len,
    380                                            isa_mask, &needs_limm);
    381 	  assert (opcode != NULL);
    382 	}
    383     }
    384 
    385   if (needs_limm && opcode != NULL)
    386     {
    387       bfd_byte buffer[4];
    388       int status;
    389 
    390       status = (*info->read_memory_func) (memaddr + *insn_len, buffer,
    391                                           4, info);
    392       if (status != 0)
    393         {
    394           opcode = NULL;
    395         }
    396       else
    397         {
    398           insn[1] = ARRANGE_ENDIAN (info, buffer);
    399           *insn_len += 4;
    400         }
    401     }
    402 
    403   if (opcode == NULL)
    404     {
    405       const struct arc_long_opcode *long_opcode;
    406 
    407       /* No instruction found yet, try the long instructions.  */
    408       long_opcode =
    409         find_format_long_instructions (insn, insn_len, isa_mask,
    410                                        memaddr, info);
    411 
    412       if (long_opcode != NULL)
    413         {
    414           iter->mode = OPERAND_ITERATOR_LONG;
    415           iter->insn = insn;
    416           iter->state.long_insn.long_opcode = long_opcode;
    417           iter->state.long_insn.opidx_base =
    418             long_opcode->base_opcode.operands;
    419           iter->state.long_insn.opidx_limm =
    420             long_opcode->operands;
    421           opcode = &long_opcode->base_opcode;
    422         }
    423     }
    424   else
    425     {
    426       iter->mode = OPERAND_ITERATOR_STANDARD;
    427       iter->insn = insn;
    428       iter->state.standard.opcode = opcode;
    429       iter->state.standard.opidx = opcode->operands;
    430     }
    431 
    432   *opcode_result = opcode;
    433   return TRUE;
    434 }
    435 
    436 static void
    437 print_flags (const struct arc_opcode *opcode,
    438 	     unsigned *insn,
    439 	     struct disassemble_info *info)
    440 {
    441   const unsigned char *flgidx;
    442   unsigned int value;
    443 
    444   /* Now extract and print the flags.  */
    445   for (flgidx = opcode->flags; *flgidx; flgidx++)
    446     {
    447       /* Get a valid flag class.  */
    448       const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
    449       const unsigned *flgopridx;
    450 
    451       /* Check first the extensions.  */
    452       if (cl_flags->flag_class & F_CLASS_EXTEND)
    453 	{
    454 	  const char *name;
    455 	  value = (insn[0] & 0x1F);
    456 
    457 	  name = arcExtMap_condCodeName (value);
    458 	  if (name)
    459 	    {
    460 	      (*info->fprintf_func) (info->stream, ".%s", name);
    461 	      continue;
    462 	    }
    463 	}
    464 
    465       for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
    466 	{
    467 	  const struct arc_flag_operand *flg_operand =
    468 	    &arc_flag_operands[*flgopridx];
    469 
    470 	  if (!flg_operand->favail)
    471 	    continue;
    472 
    473 	  value = (insn[0] >> flg_operand->shift)
    474 	    & ((1 << flg_operand->bits) - 1);
    475 	  if (value == flg_operand->code)
    476 	    {
    477 	       /* FIXME!: print correctly nt/t flag.  */
    478 	      if (!special_flag_p (opcode->name, flg_operand->name))
    479 		(*info->fprintf_func) (info->stream, ".");
    480 	      else if (info->insn_type == dis_dref)
    481 		{
    482 		  switch (flg_operand->name[0])
    483 		    {
    484 		    case 'b':
    485 		      info->data_size = 1;
    486 		      break;
    487 		    case 'h':
    488 		    case 'w':
    489 		      info->data_size = 2;
    490 		      break;
    491 		    default:
    492 		      info->data_size = 4;
    493 		      break;
    494 		    }
    495 		}
    496 	      if (flg_operand->name[0] == 'd'
    497 		  && flg_operand->name[1] == 0)
    498 		info->branch_delay_insns = 1;
    499 
    500 	      /* Check if it is a conditional flag.  */
    501 	      if (cl_flags->flag_class & F_CLASS_COND)
    502 		{
    503 		  if (info->insn_type == dis_jsr)
    504 		    info->insn_type = dis_condjsr;
    505 		  else if (info->insn_type == dis_branch)
    506 		    info->insn_type = dis_condbranch;
    507 		}
    508 
    509 	      (*info->fprintf_func) (info->stream, "%s", flg_operand->name);
    510 	    }
    511 	}
    512     }
    513 }
    514 
    515 static const char *
    516 get_auxreg (const struct arc_opcode *opcode,
    517 	    int value,
    518 	    unsigned isa_mask)
    519 {
    520   const char *name;
    521   unsigned int i;
    522   const struct arc_aux_reg *auxr = &arc_aux_regs[0];
    523 
    524   if (opcode->insn_class != AUXREG)
    525     return NULL;
    526 
    527   name = arcExtMap_auxRegName (value);
    528   if (name)
    529     return name;
    530 
    531   for (i = 0; i < arc_num_aux_regs; i++, auxr++)
    532     {
    533       if (!(auxr->cpu & isa_mask))
    534 	continue;
    535 
    536       if (auxr->subclass != NONE)
    537 	return NULL;
    538 
    539       if (auxr->address == value)
    540 	return auxr->name;
    541     }
    542   return NULL;
    543 }
    544 
    545 /* Calculate the instruction length for an instruction starting with MSB
    546    and LSB, the most and least significant byte.  The ISA_MASK is used to
    547    filter the instructions considered to only those that are part of the
    548    current architecture.
    549 
    550    The instruction lengths are calculated from the ARC_OPCODE table, and
    551    cached for later use.  */
    552 
    553 static unsigned int
    554 arc_insn_length (bfd_byte msb, bfd_byte lsb, struct disassemble_info *info)
    555 {
    556   bfd_byte major_opcode = msb >> 3;
    557 
    558   switch (info->mach)
    559     {
    560     case bfd_mach_arc_arc700:
    561       /* The nps400 extension set requires this special casing of the
    562 	 instruction length calculation.  Right now this is not causing any
    563 	 problems as none of the known extensions overlap in opcode space,
    564 	 but, if they ever do then we might need to start carrying
    565 	 information around in the elf about which extensions are in use.  */
    566       if (major_opcode == 0xb)
    567         {
    568           bfd_byte minor_opcode = lsb & 0x1f;
    569 
    570           if (minor_opcode < 4)
    571             return 2;
    572         }
    573     case bfd_mach_arc_arc600:
    574       return (major_opcode > 0xb) ? 2 : 4;
    575       break;
    576 
    577     case bfd_mach_arc_arcv2:
    578       return (major_opcode > 0x7) ? 2 : 4;
    579       break;
    580 
    581     default:
    582       abort ();
    583     }
    584 }
    585 
    586 /* Extract and return the value of OPERAND from the instruction whose value
    587    is held in the array INSN.  */
    588 
    589 static int
    590 extract_operand_value (const struct arc_operand *operand, unsigned *insn)
    591 {
    592   int value;
    593 
    594   /* Read the limm operand, if required.  */
    595   if (operand->flags & ARC_OPERAND_LIMM)
    596     /* The second part of the instruction value will have been loaded as
    597        part of the find_format call made earlier.  */
    598     value = insn[1];
    599   else
    600     {
    601       if (operand->extract)
    602         value = (*operand->extract) (insn[0], (int *) NULL);
    603       else
    604         {
    605           if (operand->flags & ARC_OPERAND_ALIGNED32)
    606             {
    607               value = (insn[0] >> operand->shift)
    608                 & ((1 << (operand->bits - 2)) - 1);
    609               value = value << 2;
    610             }
    611           else
    612             {
    613               value = (insn[0] >> operand->shift) & ((1 << operand->bits) - 1);
    614             }
    615           if (operand->flags & ARC_OPERAND_SIGNED)
    616             {
    617               int signbit = 1 << (operand->bits - 1);
    618               value = (value ^ signbit) - signbit;
    619             }
    620         }
    621     }
    622 
    623   return value;
    624 }
    625 
    626 /* Find the next operand, and the operands value from ITER.  Return TRUE if
    627    there is another operand, otherwise return FALSE.  If there is an
    628    operand returned then the operand is placed into OPERAND, and the value
    629    into VALUE.  If there is no operand returned then OPERAND and VALUE are
    630    unchanged.  */
    631 
    632 static bfd_boolean
    633 operand_iterator_next (struct arc_operand_iterator *iter,
    634                        const struct arc_operand **operand,
    635                        int *value)
    636 {
    637   if (iter->mode == OPERAND_ITERATOR_STANDARD)
    638     {
    639       if (*iter->state.standard.opidx == 0)
    640         {
    641           *operand = NULL;
    642           return FALSE;
    643         }
    644 
    645       *operand = &arc_operands[*iter->state.standard.opidx];
    646       *value = extract_operand_value (*operand, iter->insn);
    647       iter->state.standard.opidx++;
    648     }
    649   else
    650     {
    651       const struct arc_operand *operand_base, *operand_limm;
    652       int value_base, value_limm;
    653 
    654       if (*iter->state.long_insn.opidx_limm == 0)
    655         {
    656           *operand = NULL;
    657           return FALSE;
    658         }
    659 
    660       operand_base = &arc_operands[*iter->state.long_insn.opidx_base];
    661       operand_limm = &arc_operands[*iter->state.long_insn.opidx_limm];
    662 
    663       if (operand_base->flags & ARC_OPERAND_LIMM)
    664         {
    665           /* We've reached the end of the operand list.  */
    666           *operand = NULL;
    667           return FALSE;
    668         }
    669 
    670       value_base = value_limm = 0;
    671       if (!(operand_limm->flags & ARC_OPERAND_IGNORE))
    672         {
    673           /* This should never happen.  If it does then the use of
    674              extract_operand_value below will access memory beyond
    675              the insn array.  */
    676           assert ((operand_limm->flags & ARC_OPERAND_LIMM) == 0);
    677 
    678           *operand = operand_limm;
    679           value_limm = extract_operand_value (*operand, &iter->insn[1]);
    680         }
    681 
    682       if (!(operand_base->flags & ARC_OPERAND_IGNORE))
    683         {
    684           *operand = operand_base;
    685           value_base = extract_operand_value (*operand, iter->insn);
    686         }
    687 
    688       /* This is a bit of a fudge.  There's no reason why simply ORing
    689          together the two values is the right thing to do, however, for all
    690          the cases we currently have, it is the right thing, so, for now,
    691          I've put off solving the more complex problem.  */
    692       *value = value_base | value_limm;
    693 
    694       iter->state.long_insn.opidx_base++;
    695       iter->state.long_insn.opidx_limm++;
    696     }
    697   return TRUE;
    698 }
    699 
    700 /* Disassemble ARC instructions.  */
    701 
    702 static int
    703 print_insn_arc (bfd_vma memaddr,
    704 		struct disassemble_info *info)
    705 {
    706   bfd_byte buffer[4];
    707   unsigned int lowbyte, highbyte;
    708   int status;
    709   unsigned int insn_len;
    710   unsigned insn[2] = { 0, 0 };
    711   unsigned isa_mask;
    712   const struct arc_opcode *opcode;
    713   bfd_boolean need_comma;
    714   bfd_boolean open_braket;
    715   int size;
    716   const struct arc_operand *operand;
    717   int value;
    718   struct arc_operand_iterator iter;
    719 
    720   memset (&iter, 0, sizeof (iter));
    721   lowbyte  = ((info->endian == BFD_ENDIAN_LITTLE) ? 1 : 0);
    722   highbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 0 : 1);
    723 
    724   switch (info->mach)
    725     {
    726     case bfd_mach_arc_arc700:
    727       isa_mask = ARC_OPCODE_ARC700;
    728       break;
    729 
    730     case bfd_mach_arc_arc600:
    731       isa_mask = ARC_OPCODE_ARC600;
    732       break;
    733 
    734     case bfd_mach_arc_arcv2:
    735     default:
    736       isa_mask = ARC_OPCODE_ARCv2HS | ARC_OPCODE_ARCv2EM;
    737       break;
    738     }
    739 
    740   /* This variable may be set by the instruction decoder.  It suggests
    741      the number of bytes objdump should display on a single line.  If
    742      the instruction decoder sets this, it should always set it to
    743      the same value in order to get reasonable looking output.  */
    744 
    745   info->bytes_per_line  = 8;
    746 
    747   /* In the next lines, we set two info variables control the way
    748      objdump displays the raw data.  For example, if bytes_per_line is
    749      8 and bytes_per_chunk is 4, the output will look like this:
    750      00:   00000000 00000000
    751      with the chunks displayed according to "display_endian".  */
    752 
    753   if (info->section
    754       && !(info->section->flags & SEC_CODE))
    755     {
    756       /* This is not a CODE section.  */
    757       switch (info->section->size)
    758 	{
    759 	case 1:
    760 	case 2:
    761 	case 4:
    762 	  size = info->section->size;
    763 	  break;
    764 	default:
    765 	  size = (info->section->size & 0x01) ? 1 : 4;
    766 	  break;
    767 	}
    768       info->bytes_per_chunk = 1;
    769       info->display_endian = info->endian;
    770     }
    771   else
    772     {
    773       size = 2;
    774       info->bytes_per_chunk = 2;
    775       info->display_endian = info->endian;
    776     }
    777 
    778   /* Read the insn into a host word.  */
    779   status = (*info->read_memory_func) (memaddr, buffer, size, info);
    780   if (status != 0)
    781     {
    782       (*info->memory_error_func) (status, memaddr, info);
    783       return -1;
    784     }
    785 
    786   if (info->section
    787       && !(info->section->flags & SEC_CODE))
    788     {
    789       /* Data section.  */
    790       unsigned long data;
    791 
    792       data = bfd_get_bits (buffer, size * 8,
    793 			   info->display_endian == BFD_ENDIAN_BIG);
    794       switch (size)
    795 	{
    796 	case 1:
    797 	  (*info->fprintf_func) (info->stream, ".byte\t0x%02lx", data);
    798 	  break;
    799 	case 2:
    800 	  (*info->fprintf_func) (info->stream, ".short\t0x%04lx", data);
    801 	  break;
    802 	case 4:
    803 	  (*info->fprintf_func) (info->stream, ".word\t0x%08lx", data);
    804 	  break;
    805 	default:
    806 	  abort ();
    807 	}
    808       return size;
    809     }
    810 
    811   insn_len = arc_insn_length (buffer[lowbyte], buffer[highbyte], info);
    812   pr_debug ("instruction length = %d bytes\n", insn_len);
    813   switch (insn_len)
    814     {
    815     case 2:
    816       insn[0] = (buffer[lowbyte] << 8) | buffer[highbyte];
    817       break;
    818 
    819     default:
    820       /* An unknown instruction is treated as being length 4.  This is
    821          possibly not the best solution, but matches the behaviour that was
    822          in place before the table based instruction length look-up was
    823          introduced.  */
    824     case 4:
    825       /* This is a long instruction: Read the remaning 2 bytes.  */
    826       status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 2, info);
    827       if (status != 0)
    828 	{
    829 	  (*info->memory_error_func) (status, memaddr + 2, info);
    830 	  return -1;
    831 	}
    832       insn[0] = ARRANGE_ENDIAN (info, buffer);
    833       break;
    834     }
    835 
    836   /* Set some defaults for the insn info.  */
    837   info->insn_info_valid    = 1;
    838   info->branch_delay_insns = 0;
    839   info->data_size	   = 0;
    840   info->insn_type	   = dis_nonbranch;
    841   info->target		   = 0;
    842   info->target2		   = 0;
    843 
    844   /* FIXME to be moved in dissasemble_init_for_target.  */
    845   info->disassembler_needs_relocs = TRUE;
    846 
    847   /* Find the first match in the opcode table.  */
    848   if (!find_format (memaddr, insn, &insn_len, isa_mask, info, &opcode, &iter))
    849     return -1;
    850 
    851   if (!opcode)
    852     {
    853       if (insn_len == 2)
    854         (*info->fprintf_func) (info->stream, ".long %#04x", insn[0]);
    855       else
    856         (*info->fprintf_func) (info->stream, ".long %#08x", insn[0]);
    857 
    858       info->insn_type = dis_noninsn;
    859       return insn_len;
    860     }
    861 
    862   /* Print the mnemonic.  */
    863   (*info->fprintf_func) (info->stream, "%s", opcode->name);
    864 
    865   /* Preselect the insn class.  */
    866   switch (opcode->insn_class)
    867     {
    868     case BRANCH:
    869     case JUMP:
    870       if (!strncmp (opcode->name, "bl", 2)
    871 	  || !strncmp (opcode->name, "jl", 2))
    872 	{
    873 	  if (opcode->subclass == COND)
    874 	    info->insn_type = dis_condjsr;
    875 	  else
    876 	    info->insn_type = dis_jsr;
    877 	}
    878       else
    879 	{
    880 	  if (opcode->subclass == COND)
    881 	    info->insn_type = dis_condbranch;
    882 	  else
    883 	    info->insn_type = dis_branch;
    884 	}
    885       break;
    886     case MEMORY:
    887       info->insn_type = dis_dref; /* FIXME! DB indicates mov as memory! */
    888       break;
    889     default:
    890       info->insn_type = dis_nonbranch;
    891       break;
    892     }
    893 
    894   pr_debug ("%s: 0x%08x\n", opcode->name, opcode->opcode);
    895 
    896   print_flags (opcode, insn, info);
    897 
    898   if (opcode->operands[0] != 0)
    899     (*info->fprintf_func) (info->stream, "\t");
    900 
    901   need_comma = FALSE;
    902   open_braket = FALSE;
    903 
    904   /* Now extract and print the operands.  */
    905   operand = NULL;
    906   while (operand_iterator_next (&iter, &operand, &value))
    907     {
    908       if (open_braket && (operand->flags & ARC_OPERAND_BRAKET))
    909 	{
    910 	  (*info->fprintf_func) (info->stream, "]");
    911 	  open_braket = FALSE;
    912 	  continue;
    913 	}
    914 
    915       /* Only take input from real operands.  */
    916       if ((operand->flags & ARC_OPERAND_FAKE)
    917 	  && !(operand->flags & ARC_OPERAND_BRAKET))
    918 	continue;
    919 
    920       if ((operand->flags & ARC_OPERAND_IGNORE)
    921 	  && (operand->flags & ARC_OPERAND_IR)
    922           && value == -1)
    923 	continue;
    924 
    925       if (need_comma)
    926 	(*info->fprintf_func) (info->stream, ",");
    927 
    928       if (!open_braket && (operand->flags & ARC_OPERAND_BRAKET))
    929 	{
    930 	  (*info->fprintf_func) (info->stream, "[");
    931 	  open_braket = TRUE;
    932 	  need_comma = FALSE;
    933 	  continue;
    934 	}
    935 
    936       /* Print the operand as directed by the flags.  */
    937       if (operand->flags & ARC_OPERAND_IR)
    938 	{
    939 	  const char *rname;
    940 
    941 	  assert (value >=0 && value < 64);
    942 	  rname = arcExtMap_coreRegName (value);
    943 	  if (!rname)
    944 	    rname = regnames[value];
    945 	  (*info->fprintf_func) (info->stream, "%s", rname);
    946 	  if (operand->flags & ARC_OPERAND_TRUNCATE)
    947 	    {
    948 	      rname = arcExtMap_coreRegName (value + 1);
    949 	      if (!rname)
    950 		rname = regnames[value + 1];
    951 	      (*info->fprintf_func) (info->stream, "%s", rname);
    952 	    }
    953 	}
    954       else if (operand->flags & ARC_OPERAND_LIMM)
    955 	{
    956 	  const char *rname = get_auxreg (opcode, value, isa_mask);
    957 	  if (rname && open_braket)
    958 	    (*info->fprintf_func) (info->stream, "%s", rname);
    959 	  else
    960 	    {
    961 	      (*info->fprintf_func) (info->stream, "%#x", value);
    962 	      if (info->insn_type == dis_branch
    963 		  || info->insn_type == dis_jsr)
    964 		info->target = (bfd_vma) value;
    965 	    }
    966 	}
    967       else if (operand->flags & ARC_OPERAND_PCREL)
    968 	{
    969 	   /* PCL relative.  */
    970 	  if (info->flags & INSN_HAS_RELOC)
    971 	    memaddr = 0;
    972 	  (*info->print_address_func) ((memaddr & ~3) + value, info);
    973 
    974 	  info->target = (bfd_vma) (memaddr & ~3) + value;
    975 	}
    976       else if (operand->flags & ARC_OPERAND_SIGNED)
    977 	{
    978 	  const char *rname = get_auxreg (opcode, value, isa_mask);
    979 	  if (rname && open_braket)
    980 	    (*info->fprintf_func) (info->stream, "%s", rname);
    981 	  else
    982 	    (*info->fprintf_func) (info->stream, "%d", value);
    983 	}
    984       else
    985 	{
    986 	  if (operand->flags & ARC_OPERAND_TRUNCATE
    987 	      && !(operand->flags & ARC_OPERAND_ALIGNED32)
    988 	      && !(operand->flags & ARC_OPERAND_ALIGNED16)
    989 	      && value > 0 && value <= 14)
    990 	    (*info->fprintf_func) (info->stream, "r13-%s",
    991 				   regnames[13 + value - 1]);
    992 	  else
    993 	    {
    994 	      const char *rname = get_auxreg (opcode, value, isa_mask);
    995 	      if (rname && open_braket)
    996 		(*info->fprintf_func) (info->stream, "%s", rname);
    997 	      else
    998 		(*info->fprintf_func) (info->stream, "%#x", value);
    999 	    }
   1000 	}
   1001 
   1002       need_comma = TRUE;
   1003     }
   1004 
   1005   return insn_len;
   1006 }
   1007 
   1008 
   1009 disassembler_ftype
   1010 arc_get_disassembler (bfd *abfd)
   1011 {
   1012   /* Read the extenssion insns and registers, if any.  */
   1013   build_ARC_extmap (abfd);
   1014 #ifdef DEBUG
   1015   dump_ARC_extmap ();
   1016 #endif
   1017 
   1018   return print_insn_arc;
   1019 }
   1020 
   1021 /* Disassemble ARC instructions.  Used by debugger.  */
   1022 
   1023 struct arcDisState
   1024 arcAnalyzeInstr (bfd_vma memaddr,
   1025 		 struct disassemble_info *info)
   1026 {
   1027   struct arcDisState ret;
   1028   memset (&ret, 0, sizeof (struct arcDisState));
   1029 
   1030   ret.instructionLen = print_insn_arc (memaddr, info);
   1031 
   1032 #if 0
   1033   ret.words[0] = insn[0];
   1034   ret.words[1] = insn[1];
   1035   ret._this = &ret;
   1036   ret.coreRegName = _coreRegName;
   1037   ret.auxRegName = _auxRegName;
   1038   ret.condCodeName = _condCodeName;
   1039   ret.instName = _instName;
   1040 #endif
   1041 
   1042   return ret;
   1043 }
   1044 
   1045 /* Local variables:
   1046    eval: (c-set-style "gnu")
   1047    indent-tabs-mode: t
   1048    End:  */
   1049