Home | History | Annotate | Line # | Download | only in opcodes
v850-dis.c revision 1.1.1.9
      1      1.1     skrll /* Disassemble V850 instructions.
      2  1.1.1.9  christos    Copyright (C) 1996-2022 Free Software Foundation, Inc.
      3      1.1     skrll 
      4      1.1     skrll    This file is part of the GNU opcodes library.
      5      1.1     skrll 
      6      1.1     skrll    This library is free software; you can redistribute it and/or modify
      7      1.1     skrll    it under the terms of the GNU General Public License as published by
      8      1.1     skrll    the Free Software Foundation; either version 3, or (at your option)
      9      1.1     skrll    any later version.
     10      1.1     skrll 
     11      1.1     skrll    It is distributed in the hope that it will be useful, but WITHOUT
     12      1.1     skrll    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     13      1.1     skrll    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     14      1.1     skrll    License for more details.
     15      1.1     skrll 
     16      1.1     skrll    You should have received a copy of the GNU General Public License
     17      1.1     skrll    along with this program; if not, write to the Free Software
     18      1.1     skrll    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     19      1.1     skrll    MA 02110-1301, USA.  */
     20      1.1     skrll 
     21      1.1     skrll 
     22      1.1     skrll #include "sysdep.h"
     23  1.1.1.3  christos #include <stdio.h>
     24  1.1.1.4  christos #include <string.h>
     25      1.1     skrll #include "opcode/v850.h"
     26  1.1.1.6  christos #include "disassemble.h"
     27      1.1     skrll #include "opintl.h"
     28  1.1.1.8  christos #include "libiberty.h"
     29  1.1.1.4  christos 
     30  1.1.1.4  christos static const int v850_cacheop_codes[] =
     31  1.1.1.4  christos {
     32  1.1.1.4  christos   0x00, 0x20, 0x40, 0x60, 0x61, 0x04, 0x06,
     33  1.1.1.4  christos   0x07, 0x24, 0x26, 0x27, 0x44, 0x64, 0x65, -1
     34  1.1.1.4  christos };
     35  1.1.1.4  christos 
     36  1.1.1.4  christos static const int v850_prefop_codes[] =
     37  1.1.1.4  christos { 0x00, 0x04, -1};
     38  1.1.1.4  christos 
     39  1.1.1.2  christos static void
     40  1.1.1.4  christos print_value (int flags,
     41  1.1.1.4  christos 	     bfd_vma memaddr,
     42  1.1.1.4  christos 	     struct disassemble_info *info,
     43  1.1.1.4  christos 	     long value)
     44  1.1.1.2  christos {
     45  1.1.1.2  christos   if (flags & V850_PCREL)
     46  1.1.1.2  christos     {
     47  1.1.1.2  christos       bfd_vma addr = value + memaddr;
     48  1.1.1.4  christos 
     49  1.1.1.4  christos       if (flags & V850_INVERSE_PCREL)
     50  1.1.1.4  christos 	addr = memaddr - value;
     51  1.1.1.2  christos       info->print_address_func (addr, info);
     52  1.1.1.2  christos     }
     53  1.1.1.2  christos   else if (flags & V850_OPERAND_DISP)
     54  1.1.1.2  christos     {
     55  1.1.1.2  christos       if (flags & V850_OPERAND_SIGNED)
     56  1.1.1.2  christos         {
     57  1.1.1.2  christos           info->fprintf_func (info->stream, "%ld", value);
     58  1.1.1.2  christos         }
     59  1.1.1.2  christos       else
     60  1.1.1.2  christos         {
     61  1.1.1.2  christos           info->fprintf_func (info->stream, "%lu", value);
     62  1.1.1.2  christos         }
     63  1.1.1.2  christos     }
     64  1.1.1.4  christos   else if ((flags & V850E_IMMEDIATE32)
     65  1.1.1.4  christos 	   || (flags & V850E_IMMEDIATE16HI))
     66  1.1.1.2  christos     {
     67  1.1.1.2  christos       info->fprintf_func (info->stream, "0x%lx", value);
     68  1.1.1.2  christos     }
     69  1.1.1.2  christos   else
     70  1.1.1.2  christos     {
     71  1.1.1.2  christos       if (flags & V850_OPERAND_SIGNED)
     72  1.1.1.2  christos 	{
     73  1.1.1.2  christos 	  info->fprintf_func (info->stream, "%ld", value);
     74  1.1.1.2  christos 	}
     75  1.1.1.2  christos       else
     76  1.1.1.2  christos 	{
     77  1.1.1.2  christos 	  info->fprintf_func (info->stream, "%lu", value);
     78  1.1.1.2  christos 	}
     79  1.1.1.2  christos     }
     80  1.1.1.2  christos }
     81      1.1     skrll 
     82  1.1.1.2  christos static long
     83  1.1.1.2  christos get_operand_value (const struct v850_operand *operand,
     84  1.1.1.2  christos 		   unsigned long insn,
     85  1.1.1.2  christos 		   int bytes_read,
     86  1.1.1.2  christos 		   bfd_vma memaddr,
     87  1.1.1.2  christos 		   struct disassemble_info * info,
     88  1.1.1.9  christos 		   bool noerror,
     89  1.1.1.2  christos 		   int *invalid)
     90  1.1.1.2  christos {
     91  1.1.1.8  christos   unsigned long value;
     92  1.1.1.2  christos   bfd_byte buffer[4];
     93  1.1.1.2  christos 
     94  1.1.1.2  christos   if ((operand->flags & V850E_IMMEDIATE16)
     95  1.1.1.2  christos       || (operand->flags & V850E_IMMEDIATE16HI))
     96  1.1.1.2  christos     {
     97  1.1.1.2  christos       int status = info->read_memory_func (memaddr + bytes_read, buffer, 2, info);
     98  1.1.1.2  christos 
     99  1.1.1.2  christos       if (status == 0)
    100  1.1.1.2  christos 	{
    101  1.1.1.2  christos 	  value = bfd_getl16 (buffer);
    102  1.1.1.2  christos 
    103  1.1.1.2  christos 	  if (operand->flags & V850E_IMMEDIATE16HI)
    104  1.1.1.2  christos 	    value <<= 16;
    105  1.1.1.4  christos 	  else if (value & 0x8000)
    106  1.1.1.4  christos 	    value |= (-1UL << 16);
    107  1.1.1.2  christos 
    108  1.1.1.2  christos 	  return value;
    109  1.1.1.2  christos 	}
    110  1.1.1.2  christos 
    111  1.1.1.2  christos       if (!noerror)
    112  1.1.1.2  christos 	info->memory_error_func (status, memaddr + bytes_read, info);
    113  1.1.1.2  christos 
    114  1.1.1.2  christos       return 0;
    115  1.1.1.2  christos     }
    116  1.1.1.2  christos 
    117  1.1.1.2  christos   if (operand->flags & V850E_IMMEDIATE23)
    118  1.1.1.2  christos     {
    119  1.1.1.2  christos       int status = info->read_memory_func (memaddr + 2, buffer, 4, info);
    120  1.1.1.2  christos 
    121  1.1.1.2  christos       if (status == 0)
    122  1.1.1.2  christos 	{
    123  1.1.1.2  christos 	  value = bfd_getl32 (buffer);
    124  1.1.1.2  christos 
    125  1.1.1.2  christos 	  value = (operand->extract) (value, invalid);
    126  1.1.1.2  christos 
    127  1.1.1.2  christos 	  return value;
    128  1.1.1.2  christos 	}
    129  1.1.1.2  christos 
    130  1.1.1.2  christos       if (!noerror)
    131  1.1.1.2  christos 	info->memory_error_func (status, memaddr + bytes_read, info);
    132  1.1.1.2  christos 
    133  1.1.1.2  christos       return 0;
    134  1.1.1.2  christos     }
    135  1.1.1.2  christos 
    136  1.1.1.2  christos   if (operand->flags & V850E_IMMEDIATE32)
    137  1.1.1.2  christos     {
    138  1.1.1.2  christos       int status = info->read_memory_func (memaddr + bytes_read, buffer, 4, info);
    139  1.1.1.2  christos 
    140  1.1.1.2  christos       if (status == 0)
    141  1.1.1.2  christos 	{
    142  1.1.1.2  christos 	  bytes_read += 4;
    143  1.1.1.2  christos 	  value = bfd_getl32 (buffer);
    144  1.1.1.2  christos 
    145  1.1.1.2  christos 	  return value;
    146  1.1.1.2  christos 	}
    147  1.1.1.2  christos 
    148  1.1.1.2  christos       if (!noerror)
    149  1.1.1.2  christos 	info->memory_error_func (status, memaddr + bytes_read, info);
    150  1.1.1.2  christos 
    151  1.1.1.2  christos       return 0;
    152  1.1.1.2  christos     }
    153  1.1.1.2  christos 
    154  1.1.1.2  christos   if (operand->extract)
    155  1.1.1.2  christos     value = (operand->extract) (insn, invalid);
    156  1.1.1.2  christos   else
    157  1.1.1.2  christos     {
    158  1.1.1.2  christos       if (operand->bits == -1)
    159  1.1.1.2  christos 	value = (insn & operand->shift);
    160  1.1.1.2  christos       else
    161  1.1.1.8  christos 	value = (insn >> operand->shift) & ((1ul << operand->bits) - 1);
    162  1.1.1.2  christos 
    163  1.1.1.2  christos       if (operand->flags & V850_OPERAND_SIGNED)
    164  1.1.1.8  christos 	{
    165  1.1.1.8  christos 	  unsigned long sign = 1ul << (operand->bits - 1);
    166  1.1.1.8  christos 	  value = (value ^ sign) - sign;
    167  1.1.1.8  christos 	}
    168  1.1.1.2  christos     }
    169  1.1.1.2  christos 
    170  1.1.1.2  christos   return value;
    171  1.1.1.2  christos }
    172  1.1.1.2  christos 
    173  1.1.1.8  christos static const char *
    174  1.1.1.8  christos get_v850_sreg_name (unsigned int reg)
    175  1.1.1.8  christos {
    176  1.1.1.8  christos   static const char *const v850_sreg_names[] =
    177  1.1.1.8  christos     {
    178  1.1.1.8  christos      "eipc/vip/mpm", "eipsw/mpc", "fepc/tid", "fepsw/ppa", "ecr/vmecr", "psw/vmtid",
    179  1.1.1.8  christos      "sr6/fpsr/vmadr/dcc", "sr7/fpepc/dc0",
    180  1.1.1.8  christos      "sr8/fpst/vpecr/dcv1", "sr9/fpcc/vptid", "sr10/fpcfg/vpadr/spal", "sr11/spau",
    181  1.1.1.8  christos      "sr12/vdecr/ipa0l", "eiic/vdtid/ipa0u", "feic/ipa1l", "dbic/ipa1u",
    182  1.1.1.8  christos      "ctpc/ipa2l", "ctpsw/ipa2u", "dbpc/ipa3l", "dbpsw/ipa3u", "ctbp/dpa0l",
    183  1.1.1.8  christos      "dir/dpa0u", "bpc/dpa0u", "asid/dpa1l",
    184  1.1.1.8  christos      "bpav/dpa1u", "bpam/dpa2l", "bpdv/dpa2u", "bpdm/dpa3l", "eiwr/dpa3u",
    185  1.1.1.8  christos      "fewr", "dbwr", "bsel"
    186  1.1.1.8  christos     };
    187  1.1.1.8  christos 
    188  1.1.1.8  christos   if (reg < ARRAY_SIZE (v850_sreg_names))
    189  1.1.1.8  christos     return v850_sreg_names[reg];
    190  1.1.1.8  christos   return _("<invalid s-reg number>");
    191  1.1.1.8  christos }
    192  1.1.1.8  christos 
    193  1.1.1.8  christos static const char *
    194  1.1.1.8  christos get_v850_reg_name (unsigned int reg)
    195  1.1.1.8  christos {
    196  1.1.1.8  christos   static const char *const v850_reg_names[] =
    197  1.1.1.8  christos     {
    198  1.1.1.8  christos      "r0", "r1", "r2", "sp", "gp", "r5", "r6", "r7",
    199  1.1.1.8  christos      "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
    200  1.1.1.8  christos      "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
    201  1.1.1.8  christos      "r24", "r25", "r26", "r27", "r28", "r29", "ep", "lp"
    202  1.1.1.8  christos     };
    203  1.1.1.8  christos 
    204  1.1.1.8  christos   if (reg < ARRAY_SIZE (v850_reg_names))
    205  1.1.1.8  christos     return v850_reg_names[reg];
    206  1.1.1.8  christos   return _("<invalid reg number>");
    207  1.1.1.8  christos }
    208  1.1.1.8  christos 
    209  1.1.1.8  christos static const char *
    210  1.1.1.8  christos get_v850_vreg_name (unsigned int reg)
    211  1.1.1.8  christos {
    212  1.1.1.8  christos   static const char *const v850_vreg_names[] =
    213  1.1.1.8  christos     {
    214  1.1.1.8  christos      "vr0", "vr1", "vr2", "vr3", "vr4", "vr5", "vr6", "vr7", "vr8", "vr9",
    215  1.1.1.8  christos      "vr10", "vr11", "vr12", "vr13", "vr14", "vr15", "vr16", "vr17", "vr18",
    216  1.1.1.8  christos      "vr19", "vr20", "vr21", "vr22", "vr23", "vr24", "vr25", "vr26", "vr27",
    217  1.1.1.8  christos      "vr28", "vr29", "vr30", "vr31"
    218  1.1.1.8  christos     };
    219  1.1.1.8  christos 
    220  1.1.1.8  christos   if (reg < ARRAY_SIZE (v850_vreg_names))
    221  1.1.1.8  christos     return v850_vreg_names[reg];
    222  1.1.1.8  christos   return _("<invalid v-reg number>");
    223  1.1.1.8  christos }
    224  1.1.1.8  christos 
    225  1.1.1.8  christos static const char *
    226  1.1.1.8  christos get_v850_cc_name (unsigned int reg)
    227  1.1.1.8  christos {
    228  1.1.1.8  christos   static const char *const v850_cc_names[] =
    229  1.1.1.8  christos     {
    230  1.1.1.8  christos      "v", "c/l", "z", "nh", "s/n", "t", "lt", "le",
    231  1.1.1.8  christos      "nv", "nc/nl", "nz", "h", "ns/p", "sa", "ge", "gt"
    232  1.1.1.8  christos     };
    233  1.1.1.8  christos 
    234  1.1.1.8  christos   if (reg < ARRAY_SIZE (v850_cc_names))
    235  1.1.1.8  christos     return v850_cc_names[reg];
    236  1.1.1.8  christos   return _("<invalid CC-reg number>");
    237  1.1.1.8  christos }
    238  1.1.1.8  christos 
    239  1.1.1.8  christos static const char *
    240  1.1.1.8  christos get_v850_float_cc_name (unsigned int reg)
    241  1.1.1.8  christos {
    242  1.1.1.8  christos   static const char *const v850_float_cc_names[] =
    243  1.1.1.8  christos     {
    244  1.1.1.8  christos      "f/t", "un/or", "eq/neq", "ueq/ogl", "olt/uge", "ult/oge", "ole/ugt", "ule/ogt",
    245  1.1.1.8  christos      "sf/st", "ngle/gle", "seq/sne", "ngl/gl", "lt/nlt", "nge/ge", "le/nle", "ngt/gt"
    246  1.1.1.8  christos     };
    247  1.1.1.8  christos 
    248  1.1.1.8  christos   if (reg < ARRAY_SIZE (v850_float_cc_names))
    249  1.1.1.8  christos     return v850_float_cc_names[reg];
    250  1.1.1.8  christos   return _("<invalid float-CC-reg number>");
    251  1.1.1.8  christos }
    252  1.1.1.8  christos 
    253  1.1.1.8  christos static const char *
    254  1.1.1.8  christos get_v850_cacheop_name (unsigned int reg)
    255  1.1.1.8  christos {
    256  1.1.1.8  christos   static const char *const v850_cacheop_names[] =
    257  1.1.1.8  christos     {
    258  1.1.1.8  christos      "chbii", "cibii", "cfali", "cisti", "cildi", "chbid", "chbiwbd",
    259  1.1.1.8  christos      "chbwbd", "cibid", "cibiwbd", "cibwbd", "cfald", "cistd", "cildd"
    260  1.1.1.8  christos     };
    261  1.1.1.8  christos 
    262  1.1.1.8  christos   if (reg < ARRAY_SIZE (v850_cacheop_names))
    263  1.1.1.8  christos     return v850_cacheop_names[reg];
    264  1.1.1.8  christos   return _("<invalid cacheop number>");
    265  1.1.1.8  christos }
    266  1.1.1.8  christos 
    267  1.1.1.8  christos static const char *
    268  1.1.1.8  christos get_v850_prefop_name (unsigned int reg)
    269  1.1.1.8  christos {
    270  1.1.1.8  christos   static const char *const v850_prefop_names[] =
    271  1.1.1.8  christos     { "prefi", "prefd" };
    272  1.1.1.8  christos 
    273  1.1.1.8  christos   if (reg < ARRAY_SIZE (v850_prefop_names))
    274  1.1.1.8  christos     return v850_prefop_names[reg];
    275  1.1.1.8  christos   return _("<invalid prefop number>");
    276  1.1.1.8  christos }
    277  1.1.1.2  christos 
    278  1.1.1.2  christos static int
    279  1.1.1.4  christos disassemble (bfd_vma memaddr,
    280  1.1.1.4  christos 	     struct disassemble_info *info,
    281  1.1.1.4  christos 	     int bytes_read,
    282  1.1.1.4  christos 	     unsigned long insn)
    283  1.1.1.2  christos {
    284  1.1.1.4  christos   struct v850_opcode *op = (struct v850_opcode *) v850_opcodes;
    285  1.1.1.2  christos   const struct v850_operand *operand;
    286  1.1.1.2  christos   int match = 0;
    287  1.1.1.2  christos   int target_processor;
    288      1.1     skrll 
    289      1.1     skrll   switch (info->mach)
    290      1.1     skrll     {
    291      1.1     skrll     case 0:
    292      1.1     skrll     default:
    293      1.1     skrll       target_processor = PROCESSOR_V850;
    294      1.1     skrll       break;
    295      1.1     skrll 
    296      1.1     skrll     case bfd_mach_v850e:
    297      1.1     skrll       target_processor = PROCESSOR_V850E;
    298      1.1     skrll       break;
    299      1.1     skrll 
    300      1.1     skrll     case bfd_mach_v850e1:
    301  1.1.1.2  christos       target_processor = PROCESSOR_V850E;
    302  1.1.1.2  christos       break;
    303  1.1.1.2  christos 
    304  1.1.1.2  christos     case bfd_mach_v850e2:
    305  1.1.1.2  christos       target_processor = PROCESSOR_V850E2;
    306  1.1.1.2  christos       break;
    307  1.1.1.2  christos 
    308  1.1.1.2  christos     case bfd_mach_v850e2v3:
    309  1.1.1.2  christos       target_processor = PROCESSOR_V850E2V3;
    310      1.1     skrll       break;
    311  1.1.1.4  christos 
    312  1.1.1.4  christos     case bfd_mach_v850e3v5:
    313  1.1.1.4  christos       target_processor = PROCESSOR_V850E3V5;
    314  1.1.1.4  christos       break;
    315      1.1     skrll     }
    316      1.1     skrll 
    317  1.1.1.2  christos   /* If this is a two byte insn, then mask off the high bits.  */
    318  1.1.1.2  christos   if (bytes_read == 2)
    319  1.1.1.2  christos     insn &= 0xffff;
    320  1.1.1.2  christos 
    321      1.1     skrll   /* Find the opcode.  */
    322      1.1     skrll   while (op->name)
    323      1.1     skrll     {
    324      1.1     skrll       if ((op->mask & insn) == op->opcode
    325  1.1.1.2  christos 	  && (op->processors & target_processor)
    326  1.1.1.2  christos 	  && !(op->processors & PROCESSOR_OPTION_ALIAS))
    327      1.1     skrll 	{
    328  1.1.1.2  christos 	  /* Code check start.  */
    329      1.1     skrll 	  const unsigned char *opindex_ptr;
    330      1.1     skrll 	  unsigned int opnum;
    331      1.1     skrll 	  unsigned int memop;
    332      1.1     skrll 
    333  1.1.1.2  christos 	  for (opindex_ptr = op->operands, opnum = 1;
    334  1.1.1.2  christos 	       *opindex_ptr != 0;
    335  1.1.1.2  christos 	       opindex_ptr++, opnum++)
    336  1.1.1.2  christos 	    {
    337  1.1.1.2  christos 	      int invalid = 0;
    338  1.1.1.2  christos 	      long value;
    339  1.1.1.2  christos 
    340  1.1.1.2  christos 	      operand = &v850_operands[*opindex_ptr];
    341  1.1.1.2  christos 
    342  1.1.1.4  christos 	      value = get_operand_value (operand, insn, bytes_read, memaddr,
    343  1.1.1.4  christos 					 info, 1, &invalid);
    344  1.1.1.2  christos 
    345  1.1.1.2  christos 	      if (invalid)
    346  1.1.1.2  christos 		goto next_opcode;
    347  1.1.1.2  christos 
    348  1.1.1.2  christos               if ((operand->flags & V850_NOT_R0) && value == 0 && (op->memop) <=2)
    349  1.1.1.2  christos 		goto next_opcode;
    350  1.1.1.2  christos 
    351  1.1.1.2  christos 	      if ((operand->flags & V850_NOT_SA) && value == 0xd)
    352  1.1.1.2  christos 		goto next_opcode;
    353  1.1.1.2  christos 
    354  1.1.1.2  christos 	      if ((operand->flags & V850_NOT_IMM0) && value == 0)
    355  1.1.1.2  christos 		goto next_opcode;
    356  1.1.1.2  christos 	    }
    357  1.1.1.2  christos 
    358  1.1.1.2  christos 	  /* Code check end.  */
    359  1.1.1.2  christos 
    360      1.1     skrll 	  match = 1;
    361      1.1     skrll 	  (*info->fprintf_func) (info->stream, "%s\t", op->name);
    362  1.1.1.2  christos #if 0
    363  1.1.1.2  christos 	  fprintf (stderr, "match: insn: %lx, mask: %lx, opcode: %lx, name: %s\n",
    364  1.1.1.2  christos 		   insn, op->mask, op->opcode, op->name );
    365  1.1.1.2  christos #endif
    366      1.1     skrll 
    367      1.1     skrll 	  memop = op->memop;
    368      1.1     skrll 	  /* Now print the operands.
    369      1.1     skrll 
    370      1.1     skrll 	     MEMOP is the operand number at which a memory
    371      1.1     skrll 	     address specification starts, or zero if this
    372      1.1     skrll 	     instruction has no memory addresses.
    373      1.1     skrll 
    374      1.1     skrll 	     A memory address is always two arguments.
    375      1.1     skrll 
    376      1.1     skrll 	     This information allows us to determine when to
    377      1.1     skrll 	     insert commas into the output stream as well as
    378      1.1     skrll 	     when to insert disp[reg] expressions onto the
    379      1.1     skrll 	     output stream.  */
    380      1.1     skrll 
    381      1.1     skrll 	  for (opindex_ptr = op->operands, opnum = 1;
    382      1.1     skrll 	       *opindex_ptr != 0;
    383      1.1     skrll 	       opindex_ptr++, opnum++)
    384      1.1     skrll 	    {
    385  1.1.1.9  christos 	      bool square = false;
    386      1.1     skrll 	      long value;
    387      1.1     skrll 	      int flag;
    388  1.1.1.2  christos 	      char *prefix;
    389      1.1     skrll 
    390      1.1     skrll 	      operand = &v850_operands[*opindex_ptr];
    391      1.1     skrll 
    392  1.1.1.4  christos 	      value = get_operand_value (operand, insn, bytes_read, memaddr,
    393  1.1.1.4  christos 					 info, 0, 0);
    394      1.1     skrll 
    395      1.1     skrll 	      /* The first operand is always output without any
    396      1.1     skrll 		 special handling.
    397      1.1     skrll 
    398      1.1     skrll 		 For the following arguments:
    399      1.1     skrll 
    400      1.1     skrll 		   If memop && opnum == memop + 1, then we need '[' since
    401      1.1     skrll 		   we're about to output the register used in a memory
    402      1.1     skrll 		   reference.
    403      1.1     skrll 
    404      1.1     skrll 		   If memop && opnum == memop + 2, then we need ']' since
    405      1.1     skrll 		   we just finished the register in a memory reference.  We
    406      1.1     skrll 		   also need a ',' before this operand.
    407      1.1     skrll 
    408      1.1     skrll 		   Else we just need a comma.
    409      1.1     skrll 
    410      1.1     skrll 		   We may need to output a trailing ']' if the last operand
    411      1.1     skrll 		   in an instruction is the register for a memory address.
    412      1.1     skrll 
    413  1.1.1.4  christos 		   The exception (and there's always an exception) are the
    414      1.1     skrll 		   "jmp" insn which needs square brackets around it's only
    415  1.1.1.4  christos 		   register argument, and the clr1/not1/set1/tst1 insns
    416  1.1.1.4  christos 		   which [...] around their second register argument.  */
    417  1.1.1.4  christos 
    418  1.1.1.2  christos 	      prefix = "";
    419  1.1.1.2  christos 	      if (operand->flags & V850_OPERAND_BANG)
    420  1.1.1.2  christos 		{
    421  1.1.1.2  christos 		  prefix = "!";
    422  1.1.1.2  christos 		}
    423  1.1.1.2  christos 	      else if (operand->flags & V850_OPERAND_PERCENT)
    424  1.1.1.2  christos 		{
    425  1.1.1.2  christos 		  prefix = "%";
    426  1.1.1.2  christos 		}
    427      1.1     skrll 
    428  1.1.1.2  christos 	      if (opnum == 1 && opnum == memop)
    429  1.1.1.3  christos 		{
    430  1.1.1.3  christos 		  info->fprintf_func (info->stream, "%s[", prefix);
    431  1.1.1.9  christos 		  square = true;
    432  1.1.1.3  christos 		}
    433  1.1.1.4  christos 	      else if (   (strcmp ("stc.w", op->name) == 0
    434  1.1.1.4  christos 			|| strcmp ("cache", op->name) == 0
    435  1.1.1.4  christos 			|| strcmp ("pref",  op->name) == 0)
    436  1.1.1.4  christos 		       && opnum == 2 && opnum == memop)
    437  1.1.1.4  christos 		{
    438  1.1.1.4  christos 		  info->fprintf_func (info->stream, ", [");
    439  1.1.1.9  christos 		  square = true;
    440  1.1.1.4  christos 		}
    441  1.1.1.4  christos 	      else if (   (strcmp (op->name, "pushsp") == 0
    442  1.1.1.4  christos 			|| strcmp (op->name, "popsp") == 0
    443  1.1.1.4  christos 			|| strcmp (op->name, "dbpush" ) == 0)
    444  1.1.1.4  christos 		       && opnum == 2)
    445  1.1.1.4  christos 		{
    446  1.1.1.4  christos 		  info->fprintf_func (info->stream, "-");
    447  1.1.1.4  christos 		}
    448  1.1.1.2  christos 	      else if (opnum > 1
    449  1.1.1.4  christos 		       && (v850_operands[*(opindex_ptr - 1)].flags
    450  1.1.1.4  christos 			   & V850_OPERAND_DISP) != 0
    451  1.1.1.2  christos 		       && opnum == memop)
    452  1.1.1.3  christos 		{
    453  1.1.1.3  christos 		  info->fprintf_func (info->stream, "%s[", prefix);
    454  1.1.1.9  christos 		  square = true;
    455  1.1.1.3  christos 		}
    456  1.1.1.4  christos 	      else if (opnum == 2
    457  1.1.1.4  christos 		       && (   op->opcode == 0x00e407e0 /* clr1 */
    458  1.1.1.4  christos 			   || op->opcode == 0x00e207e0 /* not1 */
    459  1.1.1.4  christos 			   || op->opcode == 0x00e007e0 /* set1 */
    460  1.1.1.4  christos 			   || op->opcode == 0x00e607e0 /* tst1 */
    461  1.1.1.4  christos 			   ))
    462  1.1.1.4  christos 		{
    463  1.1.1.4  christos 		  info->fprintf_func (info->stream, ", %s[", prefix);
    464  1.1.1.9  christos 		  square = true;
    465  1.1.1.4  christos 		}
    466  1.1.1.2  christos 	      else if (opnum > 1)
    467  1.1.1.2  christos 		info->fprintf_func (info->stream, ", %s", prefix);
    468  1.1.1.2  christos 
    469  1.1.1.4  christos  	      /* Extract the flags, ignoring ones which do not
    470  1.1.1.4  christos 		 effect disassembly output.  */
    471  1.1.1.2  christos 	      flag = operand->flags & (V850_OPERAND_REG
    472  1.1.1.2  christos 				       | V850_REG_EVEN
    473  1.1.1.2  christos 				       | V850_OPERAND_EP
    474  1.1.1.2  christos 				       | V850_OPERAND_SRG
    475  1.1.1.2  christos 				       | V850E_OPERAND_REG_LIST
    476  1.1.1.2  christos 				       | V850_OPERAND_CC
    477  1.1.1.4  christos 				       | V850_OPERAND_VREG
    478  1.1.1.4  christos 				       | V850_OPERAND_CACHEOP
    479  1.1.1.4  christos 				       | V850_OPERAND_PREFOP
    480  1.1.1.2  christos 				       | V850_OPERAND_FLOAT_CC);
    481      1.1     skrll 
    482      1.1     skrll 	      switch (flag)
    483      1.1     skrll 		{
    484  1.1.1.4  christos 		case V850_OPERAND_REG:
    485  1.1.1.8  christos 		  info->fprintf_func (info->stream, "%s", get_v850_reg_name (value));
    486  1.1.1.4  christos 		  break;
    487  1.1.1.4  christos 		case (V850_OPERAND_REG|V850_REG_EVEN):
    488  1.1.1.8  christos 		  info->fprintf_func (info->stream, "%s", get_v850_reg_name (value * 2));
    489  1.1.1.4  christos 		  break;
    490  1.1.1.4  christos 		case V850_OPERAND_EP:
    491  1.1.1.4  christos 		  info->fprintf_func (info->stream, "ep");
    492  1.1.1.4  christos 		  break;
    493  1.1.1.4  christos 		case V850_OPERAND_SRG:
    494  1.1.1.8  christos 		  info->fprintf_func (info->stream, "%s", get_v850_sreg_name (value));
    495  1.1.1.4  christos 		  break;
    496  1.1.1.2  christos 		case V850E_OPERAND_REG_LIST:
    497      1.1     skrll 		  {
    498  1.1.1.2  christos 		    static int list12_regs[32]   = { 30, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    499  1.1.1.2  christos 						     0,  0, 0, 0, 0, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 };
    500      1.1     skrll 		    int *regs;
    501      1.1     skrll 		    int i;
    502  1.1.1.8  christos 		    unsigned int mask = 0;
    503      1.1     skrll 		    int pc = 0;
    504  1.1.1.2  christos 
    505      1.1     skrll 		    switch (operand->shift)
    506      1.1     skrll 		      {
    507      1.1     skrll 		      case 0xffe00001: regs = list12_regs; break;
    508      1.1     skrll 		      default:
    509      1.1     skrll 			/* xgettext:c-format */
    510  1.1.1.7  christos 			opcodes_error_handler (_("unknown operand shift: %x"),
    511  1.1.1.7  christos 					       operand->shift);
    512      1.1     skrll 			abort ();
    513      1.1     skrll 		      }
    514      1.1     skrll 
    515      1.1     skrll 		    for (i = 0; i < 32; i++)
    516      1.1     skrll 		      {
    517  1.1.1.8  christos 			if (value & (1u << i))
    518      1.1     skrll 			  {
    519      1.1     skrll 			    switch (regs[ i ])
    520      1.1     skrll 			      {
    521  1.1.1.7  christos 			      default:
    522  1.1.1.8  christos 				mask |= (1u << regs[ i ]);
    523  1.1.1.7  christos 				break;
    524  1.1.1.7  christos 			      case 0:
    525      1.1     skrll 				/* xgettext:c-format */
    526  1.1.1.7  christos 				opcodes_error_handler (_("unknown reg: %d"), i);
    527  1.1.1.7  christos 				abort ();
    528  1.1.1.7  christos 				break;
    529  1.1.1.7  christos 			      case -1:
    530  1.1.1.7  christos 				pc = 1;
    531  1.1.1.7  christos 				break;
    532      1.1     skrll 			      }
    533      1.1     skrll 			  }
    534      1.1     skrll 		      }
    535      1.1     skrll 
    536      1.1     skrll 		    info->fprintf_func (info->stream, "{");
    537      1.1     skrll 
    538  1.1.1.2  christos 		    if (mask || pc)
    539      1.1     skrll 		      {
    540      1.1     skrll 			if (mask)
    541      1.1     skrll 			  {
    542      1.1     skrll 			    unsigned int bit;
    543      1.1     skrll 			    int shown_one = 0;
    544      1.1     skrll 
    545      1.1     skrll 			    for (bit = 0; bit < 32; bit++)
    546  1.1.1.8  christos 			      if (mask & (1u << bit))
    547      1.1     skrll 				{
    548  1.1.1.8  christos 				  unsigned int first = bit;
    549  1.1.1.8  christos 				  unsigned int last;
    550      1.1     skrll 
    551      1.1     skrll 				  if (shown_one)
    552      1.1     skrll 				    info->fprintf_func (info->stream, ", ");
    553      1.1     skrll 				  else
    554      1.1     skrll 				    shown_one = 1;
    555      1.1     skrll 
    556  1.1.1.8  christos 				  info->fprintf_func (info->stream, "%s", get_v850_reg_name (first));
    557      1.1     skrll 
    558      1.1     skrll 				  for (bit++; bit < 32; bit++)
    559  1.1.1.8  christos 				    if ((mask & (1u << bit)) == 0)
    560      1.1     skrll 				      break;
    561      1.1     skrll 
    562      1.1     skrll 				  last = bit;
    563      1.1     skrll 
    564      1.1     skrll 				  if (last > first + 1)
    565  1.1.1.2  christos 				    {
    566  1.1.1.8  christos 				      info->fprintf_func (info->stream, " - %s", get_v850_reg_name (last - 1));
    567  1.1.1.2  christos 				    }
    568      1.1     skrll 				}
    569      1.1     skrll 			  }
    570      1.1     skrll 
    571      1.1     skrll 			if (pc)
    572      1.1     skrll 			  info->fprintf_func (info->stream, "%sPC", mask ? ", " : "");
    573      1.1     skrll 		      }
    574      1.1     skrll 
    575      1.1     skrll 		    info->fprintf_func (info->stream, "}");
    576      1.1     skrll 		  }
    577      1.1     skrll 		  break;
    578      1.1     skrll 
    579  1.1.1.4  christos 		case V850_OPERAND_CC:
    580  1.1.1.8  christos 		  info->fprintf_func (info->stream, "%s", get_v850_cc_name (value));
    581  1.1.1.4  christos 		  break;
    582  1.1.1.4  christos 
    583  1.1.1.4  christos 		case V850_OPERAND_FLOAT_CC:
    584  1.1.1.8  christos 		  info->fprintf_func (info->stream, "%s", get_v850_float_cc_name (value));
    585  1.1.1.4  christos 		  break;
    586  1.1.1.4  christos 
    587  1.1.1.4  christos 		case V850_OPERAND_CACHEOP:
    588  1.1.1.4  christos 		  {
    589  1.1.1.4  christos 		    int idx;
    590  1.1.1.4  christos 
    591  1.1.1.4  christos 		    for (idx = 0; v850_cacheop_codes[idx] != -1; idx++)
    592  1.1.1.4  christos 		      {
    593  1.1.1.4  christos 			if (value == v850_cacheop_codes[idx])
    594  1.1.1.4  christos 			  {
    595  1.1.1.4  christos 			    info->fprintf_func (info->stream, "%s",
    596  1.1.1.8  christos 						get_v850_cacheop_name (idx));
    597  1.1.1.4  christos 			    goto MATCH_CACHEOP_CODE;
    598  1.1.1.4  christos 			  }
    599  1.1.1.4  christos 		      }
    600  1.1.1.4  christos 		    info->fprintf_func (info->stream, "%d", (int) value);
    601  1.1.1.4  christos 		  }
    602  1.1.1.4  christos 		MATCH_CACHEOP_CODE:
    603  1.1.1.4  christos 		  break;
    604  1.1.1.4  christos 
    605  1.1.1.4  christos 		case V850_OPERAND_PREFOP:
    606  1.1.1.4  christos 		  {
    607  1.1.1.4  christos 		    int idx;
    608  1.1.1.4  christos 
    609  1.1.1.4  christos 		    for (idx = 0; v850_prefop_codes[idx] != -1; idx++)
    610  1.1.1.4  christos 		      {
    611  1.1.1.4  christos 			if (value == v850_prefop_codes[idx])
    612  1.1.1.4  christos 			  {
    613  1.1.1.4  christos 			    info->fprintf_func (info->stream, "%s",
    614  1.1.1.8  christos 						get_v850_prefop_name (idx));
    615  1.1.1.4  christos 			    goto MATCH_PREFOP_CODE;
    616  1.1.1.4  christos 			  }
    617  1.1.1.4  christos 		      }
    618  1.1.1.4  christos 		    info->fprintf_func (info->stream, "%d", (int) value);
    619  1.1.1.4  christos 		  }
    620  1.1.1.4  christos 		MATCH_PREFOP_CODE:
    621  1.1.1.4  christos 		  break;
    622  1.1.1.4  christos 
    623  1.1.1.4  christos 		case V850_OPERAND_VREG:
    624  1.1.1.8  christos 		  info->fprintf_func (info->stream, "%s", get_v850_vreg_name (value));
    625  1.1.1.4  christos 		  break;
    626  1.1.1.2  christos 
    627  1.1.1.2  christos 		default:
    628  1.1.1.2  christos 		  print_value (operand->flags, memaddr, info, value);
    629      1.1     skrll 		  break;
    630      1.1     skrll 		}
    631      1.1     skrll 
    632  1.1.1.3  christos 	      if (square)
    633      1.1     skrll 		(*info->fprintf_func) (info->stream, "]");
    634      1.1     skrll 	    }
    635      1.1     skrll 
    636      1.1     skrll 	  /* All done. */
    637      1.1     skrll 	  break;
    638      1.1     skrll 	}
    639  1.1.1.2  christos     next_opcode:
    640      1.1     skrll       op++;
    641      1.1     skrll     }
    642      1.1     skrll 
    643  1.1.1.2  christos   return match;
    644      1.1     skrll }
    645      1.1     skrll 
    646      1.1     skrll int
    647      1.1     skrll print_insn_v850 (bfd_vma memaddr, struct disassemble_info * info)
    648      1.1     skrll {
    649  1.1.1.2  christos   int status, status2, match;
    650  1.1.1.2  christos   bfd_byte buffer[8];
    651  1.1.1.2  christos   int length = 0, code_length = 0;
    652  1.1.1.2  christos   unsigned long insn = 0, insn2 = 0;
    653  1.1.1.2  christos   int target_processor;
    654  1.1.1.2  christos 
    655  1.1.1.2  christos   switch (info->mach)
    656  1.1.1.2  christos     {
    657  1.1.1.2  christos     case 0:
    658  1.1.1.2  christos     default:
    659  1.1.1.2  christos       target_processor = PROCESSOR_V850;
    660  1.1.1.2  christos       break;
    661  1.1.1.2  christos 
    662  1.1.1.2  christos     case bfd_mach_v850e:
    663  1.1.1.2  christos       target_processor = PROCESSOR_V850E;
    664  1.1.1.2  christos       break;
    665  1.1.1.2  christos 
    666  1.1.1.2  christos     case bfd_mach_v850e1:
    667  1.1.1.2  christos       target_processor = PROCESSOR_V850E;
    668  1.1.1.2  christos       break;
    669  1.1.1.2  christos 
    670  1.1.1.2  christos     case bfd_mach_v850e2:
    671  1.1.1.2  christos       target_processor = PROCESSOR_V850E2;
    672  1.1.1.2  christos       break;
    673  1.1.1.2  christos 
    674  1.1.1.2  christos     case bfd_mach_v850e2v3:
    675  1.1.1.2  christos       target_processor = PROCESSOR_V850E2V3;
    676  1.1.1.2  christos       break;
    677  1.1.1.4  christos 
    678  1.1.1.4  christos     case bfd_mach_v850e3v5:
    679  1.1.1.4  christos       target_processor = PROCESSOR_V850E3V5;
    680  1.1.1.4  christos       break;
    681  1.1.1.2  christos     }
    682      1.1     skrll 
    683      1.1     skrll   status = info->read_memory_func (memaddr, buffer, 2, info);
    684  1.1.1.2  christos 
    685  1.1.1.2  christos   if (status)
    686      1.1     skrll     {
    687  1.1.1.2  christos       info->memory_error_func (status, memaddr, info);
    688  1.1.1.2  christos       return -1;
    689  1.1.1.2  christos     }
    690      1.1     skrll 
    691  1.1.1.2  christos   insn = bfd_getl16 (buffer);
    692  1.1.1.2  christos 
    693  1.1.1.2  christos   status2 = info->read_memory_func (memaddr+2, buffer, 2 , info);
    694  1.1.1.2  christos 
    695  1.1.1.2  christos   if (!status2)
    696  1.1.1.2  christos     {
    697  1.1.1.2  christos       insn2 = bfd_getl16 (buffer);
    698  1.1.1.2  christos       /* fprintf (stderr, "insn2 0x%08lx\n", insn2); */
    699  1.1.1.2  christos     }
    700  1.1.1.2  christos 
    701  1.1.1.2  christos   /* Special case.  */
    702  1.1.1.2  christos   if (length == 0
    703  1.1.1.4  christos       && ((target_processor & PROCESSOR_V850E2_UP) != 0))
    704  1.1.1.2  christos     {
    705  1.1.1.2  christos       if ((insn & 0xffff) == 0x02e0		/* jr 32bit */
    706  1.1.1.2  christos 	  && !status2 && (insn2 & 0x1) == 0)
    707  1.1.1.2  christos 	{
    708  1.1.1.2  christos 	  length = 2;
    709  1.1.1.2  christos 	  code_length = 6;
    710  1.1.1.2  christos 	}
    711  1.1.1.2  christos       else if ((insn & 0xffe0) == 0x02e0	/* jarl 32bit */
    712  1.1.1.2  christos 	       && !status2 && (insn2 & 0x1) == 0)
    713  1.1.1.2  christos 	{
    714  1.1.1.2  christos 	  length = 2;
    715  1.1.1.2  christos 	  code_length = 6;
    716  1.1.1.2  christos 	}
    717  1.1.1.2  christos       else if ((insn & 0xffe0) == 0x06e0	/* jmp 32bit */
    718  1.1.1.2  christos 	       && !status2 && (insn2 & 0x1) == 0)
    719      1.1     skrll 	{
    720  1.1.1.2  christos 	  length = 2;
    721  1.1.1.2  christos 	  code_length = 6;
    722  1.1.1.2  christos 	}
    723  1.1.1.2  christos     }
    724      1.1     skrll 
    725  1.1.1.2  christos   if (length == 0
    726  1.1.1.4  christos       && ((target_processor & PROCESSOR_V850E3V5_UP) != 0))
    727  1.1.1.4  christos     {
    728  1.1.1.4  christos       if (   ((insn & 0xffe0) == 0x07a0		/* ld.dw 23bit (v850e3v5) */
    729  1.1.1.4  christos 	      && !status2 && (insn2 & 0x000f) == 0x0009)
    730  1.1.1.4  christos 	  || ((insn & 0xffe0) == 0x07a0		/* st.dw 23bit (v850e3v5) */
    731  1.1.1.4  christos 	      && !status2 && (insn2 & 0x000f) == 0x000f))
    732  1.1.1.4  christos 	{
    733  1.1.1.4  christos 	  length = 4;
    734  1.1.1.4  christos 	  code_length = 6;
    735  1.1.1.4  christos 	}
    736  1.1.1.4  christos     }
    737  1.1.1.4  christos 
    738  1.1.1.4  christos   if (length == 0
    739  1.1.1.4  christos       && ((target_processor & PROCESSOR_V850E2V3_UP) != 0))
    740  1.1.1.2  christos     {
    741  1.1.1.2  christos       if (((insn & 0xffe0) == 0x0780		/* ld.b 23bit */
    742  1.1.1.2  christos 	   && !status2 && (insn2 & 0x000f) == 0x0005)
    743  1.1.1.2  christos 	  || ((insn & 0xffe0) == 0x07a0		/* ld.bu 23bit */
    744  1.1.1.2  christos 	      && !status2 && (insn2 & 0x000f) == 0x0005)
    745  1.1.1.2  christos 	  || ((insn & 0xffe0) == 0x0780		/* ld.h 23bit */
    746  1.1.1.2  christos 	      && !status2 && (insn2 & 0x000f) == 0x0007)
    747  1.1.1.2  christos 	  || ((insn & 0xffe0) == 0x07a0		/* ld.hu 23bit */
    748  1.1.1.2  christos 	      && !status2 && (insn2 & 0x000f) == 0x0007)
    749  1.1.1.2  christos 	  || ((insn & 0xffe0) == 0x0780		/* ld.w 23bit */
    750  1.1.1.2  christos 	      && !status2 && (insn2 & 0x000f) == 0x0009))
    751  1.1.1.2  christos 	{
    752  1.1.1.2  christos 	  length = 4;
    753  1.1.1.2  christos 	  code_length = 6;
    754  1.1.1.2  christos 	}
    755  1.1.1.2  christos       else if (((insn & 0xffe0) == 0x0780	/* st.b 23bit */
    756  1.1.1.2  christos 	       && !status2 && (insn2 & 0x000f) == 0x000d)
    757  1.1.1.2  christos 	      || ((insn & 0xffe0) == 0x07a0	/* st.h 23bit */
    758  1.1.1.2  christos 		  && !status2 && (insn2 & 0x000f) == 0x000d)
    759  1.1.1.2  christos 	      || ((insn & 0xffe0) == 0x0780	/* st.w 23bit */
    760  1.1.1.2  christos 		  && !status2 && (insn2 & 0x000f) == 0x000f))
    761  1.1.1.2  christos 	{
    762  1.1.1.2  christos 	  length = 4;
    763  1.1.1.2  christos 	  code_length = 6;
    764      1.1     skrll 	}
    765      1.1     skrll     }
    766      1.1     skrll 
    767  1.1.1.2  christos   if (length == 0
    768  1.1.1.2  christos       && target_processor != PROCESSOR_V850)
    769      1.1     skrll     {
    770  1.1.1.2  christos       if ((insn & 0xffe0) == 0x0620)		/* 32 bit MOV */
    771  1.1.1.2  christos 	{
    772  1.1.1.2  christos 	  length = 2;
    773  1.1.1.2  christos 	  code_length = 6;
    774  1.1.1.2  christos 	}
    775  1.1.1.2  christos       else if ((insn & 0xffc0) == 0x0780	/* prepare {list}, imm5, imm16<<16 */
    776  1.1.1.2  christos 	       && !status2 && (insn2 & 0x001f) == 0x0013)
    777  1.1.1.2  christos 	{
    778  1.1.1.2  christos 	  length = 4;
    779  1.1.1.2  christos 	  code_length = 6;
    780  1.1.1.2  christos 	}
    781  1.1.1.2  christos       else if ((insn & 0xffc0) == 0x0780	/* prepare {list}, imm5, imm16 */
    782  1.1.1.2  christos 	       && !status2 && (insn2 & 0x001f) == 0x000b)
    783  1.1.1.2  christos 	{
    784  1.1.1.2  christos 	  length = 4;
    785  1.1.1.2  christos 	  code_length = 6;
    786  1.1.1.2  christos 	}
    787  1.1.1.2  christos       else if ((insn & 0xffc0) == 0x0780	/* prepare {list}, imm5, imm32 */
    788  1.1.1.2  christos 	       && !status2 && (insn2 & 0x001f) == 0x001b)
    789  1.1.1.2  christos 	{
    790  1.1.1.2  christos 	  length = 4;
    791  1.1.1.2  christos 	  code_length = 8;
    792  1.1.1.2  christos 	}
    793  1.1.1.2  christos     }
    794  1.1.1.2  christos 
    795  1.1.1.2  christos   if (length == 4
    796  1.1.1.2  christos       || (length == 0
    797  1.1.1.2  christos 	  && (insn & 0x0600) == 0x0600))
    798  1.1.1.2  christos     {
    799  1.1.1.2  christos       /* This is a 4 byte insn.  */
    800  1.1.1.2  christos       status = info->read_memory_func (memaddr, buffer, 4, info);
    801  1.1.1.2  christos       if (!status)
    802  1.1.1.2  christos 	{
    803  1.1.1.2  christos 	  insn = bfd_getl32 (buffer);
    804  1.1.1.2  christos 
    805  1.1.1.2  christos 	  if (!length)
    806  1.1.1.2  christos 	    length = code_length = 4;
    807  1.1.1.2  christos 	}
    808  1.1.1.2  christos     }
    809  1.1.1.2  christos 
    810  1.1.1.2  christos   if (code_length > length)
    811  1.1.1.2  christos     {
    812  1.1.1.2  christos       status = info->read_memory_func (memaddr + length, buffer, code_length - length, info);
    813  1.1.1.2  christos       if (status)
    814  1.1.1.2  christos 	length = 0;
    815  1.1.1.2  christos     }
    816  1.1.1.2  christos 
    817  1.1.1.2  christos   if (length == 0 && !status)
    818  1.1.1.2  christos     length = code_length = 2;
    819  1.1.1.2  christos 
    820  1.1.1.2  christos   if (length == 2)
    821  1.1.1.2  christos     insn &= 0xffff;
    822  1.1.1.2  christos 
    823  1.1.1.4  christos   /* when the last 2 bytes of section is 0xffff, length will be 0 and cause infinitive loop */
    824  1.1.1.4  christos   if (length == 0)
    825  1.1.1.4  christos     return -1;
    826  1.1.1.4  christos 
    827  1.1.1.2  christos   match = disassemble (memaddr, info, length, insn);
    828  1.1.1.2  christos 
    829  1.1.1.2  christos   if (!match)
    830  1.1.1.2  christos     {
    831  1.1.1.2  christos       int l = 0;
    832  1.1.1.2  christos 
    833  1.1.1.2  christos       status = info->read_memory_func (memaddr, buffer, code_length, info);
    834  1.1.1.2  christos 
    835  1.1.1.2  christos       while (l < code_length)
    836  1.1.1.2  christos 	{
    837  1.1.1.2  christos 	  if (code_length - l == 2)
    838  1.1.1.2  christos 	    {
    839  1.1.1.2  christos 	      insn = bfd_getl16 (buffer + l) & 0xffff;
    840  1.1.1.2  christos 	      info->fprintf_func (info->stream, ".short\t0x%04lx", insn);
    841  1.1.1.2  christos 	      l += 2;
    842  1.1.1.2  christos 	    }
    843  1.1.1.2  christos 	  else
    844  1.1.1.2  christos 	    {
    845  1.1.1.2  christos 	      insn = bfd_getl32 (buffer + l);
    846  1.1.1.2  christos 	      info->fprintf_func (info->stream, ".long\t0x%08lx", insn);
    847  1.1.1.2  christos 	      l += 4;
    848  1.1.1.2  christos 	    }
    849  1.1.1.2  christos 	}
    850      1.1     skrll     }
    851      1.1     skrll 
    852  1.1.1.2  christos   return code_length;
    853      1.1     skrll }
    854