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