Home | History | Annotate | Download | only in opcodes
      1 /* Disassemble MN10300 instructions.
      2    Copyright (C) 1996-2014 Free Software Foundation, Inc.
      3 
      4    This file is part of the GNU opcodes library.
      5 
      6    This library is free software; you can redistribute it and/or modify
      7    it under the terms of the GNU General Public License as published by
      8    the Free Software Foundation; either version 3, or (at your option)
      9    any later version.
     10 
     11    It is distributed in the hope that it will be useful, but WITHOUT
     12    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     13    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     14    License for more details.
     15 
     16    You should have received a copy of the GNU General Public License
     17    along with this program; if not, write to the Free Software
     18    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     19    MA 02110-1301, USA.  */
     20 
     21 #include "sysdep.h"
     22 #include <stdio.h>
     23 #include "opcode/mn10300.h"
     24 #include "dis-asm.h"
     25 #include "opintl.h"
     26 
     27 #define HAVE_AM33_2 (info->mach == AM33_2)
     28 #define HAVE_AM33   (info->mach == AM33 || HAVE_AM33_2)
     29 #define HAVE_AM30   (info->mach == AM30)
     30 
     31 static void
     32 disassemble (bfd_vma memaddr,
     33 	     struct disassemble_info *info,
     34 	     unsigned long insn,
     35 	     unsigned int size)
     36 {
     37   struct mn10300_opcode *op = (struct mn10300_opcode *) mn10300_opcodes;
     38   const struct mn10300_operand *operand;
     39   bfd_byte buffer[4];
     40   unsigned long extension = 0;
     41   int status, match = 0;
     42 
     43   /* Find the opcode.  */
     44   while (op->name)
     45     {
     46       int mysize, extra_shift;
     47 
     48       if (op->format == FMT_S0)
     49 	mysize = 1;
     50       else if (op->format == FMT_S1
     51 	       || op->format == FMT_D0)
     52 	mysize = 2;
     53       else if (op->format == FMT_S2
     54 	       || op->format == FMT_D1)
     55 	mysize = 3;
     56       else if (op->format == FMT_S4)
     57 	mysize = 5;
     58       else if (op->format == FMT_D2)
     59 	mysize = 4;
     60       else if (op->format == FMT_D3)
     61 	mysize = 5;
     62       else if (op->format == FMT_D4)
     63 	mysize = 6;
     64       else if (op->format == FMT_D6)
     65 	mysize = 3;
     66       else if (op->format == FMT_D7 || op->format == FMT_D10)
     67 	mysize = 4;
     68       else if (op->format == FMT_D8)
     69 	mysize = 6;
     70       else if (op->format == FMT_D9)
     71 	mysize = 7;
     72       else
     73 	mysize = 7;
     74 
     75       if ((op->mask & insn) == op->opcode
     76 	  && size == (unsigned int) mysize
     77 	  && (op->machine == 0
     78 	      || (op->machine == AM33_2 && HAVE_AM33_2)
     79 	      || (op->machine == AM33 && HAVE_AM33)
     80 	      || (op->machine == AM30 && HAVE_AM30)))
     81 	{
     82 	  const unsigned char *opindex_ptr;
     83 	  unsigned int nocomma;
     84 	  int paren = 0;
     85 
     86 	  if (op->format == FMT_D1 || op->format == FMT_S1)
     87 	    extra_shift = 8;
     88 	  else if (op->format == FMT_D2 || op->format == FMT_D4
     89 		   || op->format == FMT_S2 || op->format == FMT_S4
     90 		   || op->format == FMT_S6 || op->format == FMT_D5)
     91 	    extra_shift = 16;
     92 	  else if (op->format == FMT_D7
     93 		   || op->format == FMT_D8
     94 		   || op->format == FMT_D9)
     95 	    extra_shift = 8;
     96 	  else
     97 	    extra_shift = 0;
     98 
     99 	  if (size == 1 || size == 2)
    100 	    extension = 0;
    101 
    102 	  else if (size == 3
    103 		   && (op->format == FMT_D1
    104 		       || op->opcode == 0xdf0000
    105 		       || op->opcode == 0xde0000))
    106 	    extension = 0;
    107 
    108 	  else if (size == 3
    109 		   && op->format == FMT_D6)
    110 	    extension = 0;
    111 
    112 	  else if (size == 3)
    113 	    {
    114 	      insn &= 0xff0000;
    115 	      status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
    116 	      if (status != 0)
    117 		{
    118 		  (*info->memory_error_func) (status, memaddr, info);
    119 		  return;
    120 		}
    121 
    122 	      insn |= bfd_getl16 (buffer);
    123 	      extension = 0;
    124 	    }
    125 	  else if (size == 4
    126 		   && (op->opcode == 0xfaf80000
    127 		       || op->opcode == 0xfaf00000
    128 		       || op->opcode == 0xfaf40000))
    129 	    extension = 0;
    130 
    131 	  else if (size == 4
    132 		   && (op->format == FMT_D7
    133 		       || op->format == FMT_D10))
    134 	    extension = 0;
    135 
    136 	  else if (size == 4)
    137 	    {
    138 	      insn &= 0xffff0000;
    139 	      status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
    140 	      if (status != 0)
    141 		{
    142 		  (*info->memory_error_func) (status, memaddr, info);
    143 		  return;
    144 		}
    145 
    146 	      insn |= bfd_getl16 (buffer);
    147 	      extension = 0;
    148 	    }
    149 	  else if (size == 5 && op->opcode == 0xdc000000)
    150 	    {
    151 	      unsigned long temp = 0;
    152 
    153 	      status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
    154 	      if (status != 0)
    155 		{
    156 		  (*info->memory_error_func) (status, memaddr, info);
    157 		  return;
    158 		}
    159 	      temp |= bfd_getl32 (buffer);
    160 
    161 	      insn &= 0xff000000;
    162 	      insn |= (temp & 0xffffff00) >> 8;
    163 	      extension = temp & 0xff;
    164 	    }
    165 	  else if (size == 5 && op->format == FMT_D3)
    166 	    {
    167 	      status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
    168 	      if (status != 0)
    169 		{
    170 		  (*info->memory_error_func) (status, memaddr, info);
    171 		  return;
    172 		}
    173 	      insn &= 0xffff0000;
    174 	      insn |= bfd_getl16 (buffer);
    175 
    176 	      status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
    177 	      if (status != 0)
    178 		{
    179 		  (*info->memory_error_func) (status, memaddr, info);
    180 		  return;
    181 		}
    182 	      extension = *(unsigned char *) buffer;
    183 	    }
    184 	  else if (size == 5)
    185 	    {
    186 	      unsigned long temp = 0;
    187 
    188 	      status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
    189 	      if (status != 0)
    190 		{
    191 		  (*info->memory_error_func) (status, memaddr, info);
    192 		  return;
    193 		}
    194 	      temp |= bfd_getl16 (buffer);
    195 
    196 	      insn &= 0xff0000ff;
    197 	      insn |= temp << 8;
    198 
    199 	      status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
    200 	      if (status != 0)
    201 		{
    202 		  (*info->memory_error_func) (status, memaddr, info);
    203 		  return;
    204 		}
    205 	      extension = *(unsigned char *) buffer;
    206 	    }
    207 	  else if (size == 6 && op->format == FMT_D8)
    208 	    {
    209 	      insn &= 0xffffff00;
    210 	      status = (*info->read_memory_func) (memaddr + 5, buffer, 1, info);
    211 	      if (status != 0)
    212 		{
    213 		  (*info->memory_error_func) (status, memaddr, info);
    214 		  return;
    215 		}
    216 	      insn |= *(unsigned char *) buffer;
    217 
    218 	      status = (*info->read_memory_func) (memaddr + 3, buffer, 2, info);
    219 	      if (status != 0)
    220 		{
    221 		  (*info->memory_error_func) (status, memaddr, info);
    222 		  return;
    223 		}
    224 	      extension = bfd_getl16 (buffer);
    225 	    }
    226 	  else if (size == 6)
    227 	    {
    228 	      unsigned long temp = 0;
    229 
    230 	      status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
    231 	      if (status != 0)
    232 		{
    233 		  (*info->memory_error_func) (status, memaddr, info);
    234 		  return;
    235 		}
    236 	      temp |= bfd_getl32 (buffer);
    237 
    238 	      insn &= 0xffff0000;
    239 	      insn |= (temp >> 16) & 0xffff;
    240 	      extension = temp & 0xffff;
    241 	    }
    242 	  else if (size == 7 && op->format == FMT_D9)
    243 	    {
    244 	      insn &= 0xffffff00;
    245 	      status = (*info->read_memory_func) (memaddr + 3, buffer, 4, info);
    246 	      if (status != 0)
    247 		{
    248 		  (*info->memory_error_func) (status, memaddr, info);
    249 		  return;
    250 		}
    251 	      extension = bfd_getl32 (buffer);
    252 	      insn |= (extension & 0xff000000) >> 24;
    253 	      extension &= 0xffffff;
    254 	    }
    255 	  else if (size == 7 && op->opcode == 0xdd000000)
    256 	    {
    257 	      unsigned long temp = 0;
    258 
    259 	      status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
    260 	      if (status != 0)
    261 		{
    262 		  (*info->memory_error_func) (status, memaddr, info);
    263 		  return;
    264 		}
    265 	      temp |= bfd_getl32 (buffer);
    266 
    267 	      insn &= 0xff000000;
    268 	      insn |= (temp >> 8) & 0xffffff;
    269 	      extension = (temp & 0xff) << 16;
    270 
    271 	      status = (*info->read_memory_func) (memaddr + 5, buffer, 2, info);
    272 	      if (status != 0)
    273 		{
    274 		  (*info->memory_error_func) (status, memaddr, info);
    275 		  return;
    276 		}
    277 	      extension |= bfd_getb16 (buffer);
    278 	    }
    279 	  else if (size == 7)
    280 	    {
    281 	      unsigned long temp = 0;
    282 
    283 	      status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
    284 	      if (status != 0)
    285 		{
    286 		  (*info->memory_error_func) (status, memaddr, info);
    287 		  return;
    288 		}
    289 	      temp |= bfd_getl32 (buffer);
    290 
    291 	      insn &= 0xffff0000;
    292 	      insn |= (temp >> 16) & 0xffff;
    293 	      extension = (temp & 0xffff) << 8;
    294 
    295 	      status = (*info->read_memory_func) (memaddr + 6, buffer, 1, info);
    296 	      if (status != 0)
    297 		{
    298 		  (*info->memory_error_func) (status, memaddr, info);
    299 		  return;
    300 		}
    301 	      extension |= *(unsigned char *) buffer;
    302 	    }
    303 
    304 	  match = 1;
    305 	  (*info->fprintf_func) (info->stream, "%s\t", op->name);
    306 
    307 	  /* Now print the operands.  */
    308 	  for (opindex_ptr = op->operands, nocomma = 1;
    309 	       *opindex_ptr != 0;
    310 	       opindex_ptr++)
    311 	    {
    312 	      unsigned long value;
    313 
    314 	      operand = &mn10300_operands[*opindex_ptr];
    315 
    316 	      /* If this operand is a PLUS (autoincrement), then do not emit
    317 		 a comma before emitting the plus.  */
    318 	      if ((operand->flags & MN10300_OPERAND_PLUS) != 0)
    319 		nocomma = 1;
    320 
    321 	      if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
    322 		{
    323 		  unsigned long temp;
    324 
    325 		  value = insn & ((1 << operand->bits) - 1);
    326 		  value <<= (32 - operand->bits);
    327 		  temp = extension >> operand->shift;
    328 		  temp &= ((1 << (32 - operand->bits)) - 1);
    329 		  value |= temp;
    330 		  value = ((value ^ (((unsigned long) 1) << 31))
    331 			   - (((unsigned long) 1) << 31));
    332 		}
    333 	      else if ((operand->flags & MN10300_OPERAND_24BIT) != 0)
    334 		{
    335 		  unsigned long temp;
    336 
    337 		  value = insn & ((1 << operand->bits) - 1);
    338 		  value <<= (24 - operand->bits);
    339 		  temp = extension >> operand->shift;
    340 		  temp &= ((1 << (24 - operand->bits)) - 1);
    341 		  value |= temp;
    342 		  if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
    343 		    value = ((value & 0xffffff) ^ 0x800000) - 0x800000;
    344 		}
    345 	      else if ((operand->flags & (MN10300_OPERAND_FSREG
    346 					  | MN10300_OPERAND_FDREG)))
    347 		{
    348 		  /* See m10300-opc.c just before #define FSM0 for an
    349 		     explanation of these variables.  Note that
    350 		     FMT-implied shifts are not taken into account for
    351 		     FP registers.  */
    352 		  unsigned long mask_low, mask_high;
    353 		  int shl_low, shr_high, shl_high;
    354 
    355 		  switch (operand->bits)
    356 		    {
    357 		    case 5:
    358 		      /* Handle regular FP registers.  */
    359 		      if (operand->shift >= 0)
    360 			{
    361 			  /* This is an `m' register.  */
    362 			  shl_low = operand->shift;
    363 			  shl_high = 8 + (8 & shl_low) + (shl_low & 4) / 4;
    364 			}
    365 		      else
    366 			{
    367 			  /* This is an `n' register.  */
    368 			  shl_low = -operand->shift;
    369 			  shl_high = shl_low / 4;
    370 			}
    371 		      mask_low = 0x0f;
    372 		      mask_high = 0x10;
    373 		      shr_high = 4;
    374 		      break;
    375 
    376 		    case 3:
    377 		      /* Handle accumulators.  */
    378 		      shl_low = -operand->shift;
    379 		      shl_high = 0;
    380 		      mask_low = 0x03;
    381 		      mask_high = 0x04;
    382 		      shr_high = 2;
    383 		      break;
    384 
    385 		    default:
    386 		      abort ();
    387 		    }
    388 		  value = ((((insn >> shl_high) << shr_high) & mask_high)
    389 			   | ((insn >> shl_low) & mask_low));
    390 		}
    391 	      else if ((operand->flags & MN10300_OPERAND_EXTENDED) != 0)
    392 		value = ((extension >> (operand->shift))
    393 			 & ((1 << operand->bits) - 1));
    394 
    395 	      else
    396 		value = ((insn >> (operand->shift))
    397 			 & ((1 << operand->bits) - 1));
    398 
    399 	      if ((operand->flags & MN10300_OPERAND_SIGNED) != 0
    400 		  /* These are properly extended by the code above.  */
    401 		  && ((operand->flags & MN10300_OPERAND_24BIT) == 0))
    402 		value = ((value ^ (((unsigned long) 1) << (operand->bits - 1)))
    403 			 - (((unsigned long) 1) << (operand->bits - 1)));
    404 
    405 	      if (!nocomma
    406 		  && (!paren
    407 		      || ((operand->flags & MN10300_OPERAND_PAREN) == 0)))
    408 		(*info->fprintf_func) (info->stream, ",");
    409 
    410 	      nocomma = 0;
    411 
    412 	      if ((operand->flags & MN10300_OPERAND_DREG) != 0)
    413 		{
    414 		  value = ((insn >> (operand->shift + extra_shift))
    415 			   & ((1 << operand->bits) - 1));
    416 		  (*info->fprintf_func) (info->stream, "d%d", (int) value);
    417 		}
    418 
    419 	      else if ((operand->flags & MN10300_OPERAND_AREG) != 0)
    420 		{
    421 		  value = ((insn >> (operand->shift + extra_shift))
    422 			   & ((1 << operand->bits) - 1));
    423 		  (*info->fprintf_func) (info->stream, "a%d", (int) value);
    424 		}
    425 
    426 	      else if ((operand->flags & MN10300_OPERAND_SP) != 0)
    427 		(*info->fprintf_func) (info->stream, "sp");
    428 
    429 	      else if ((operand->flags & MN10300_OPERAND_PSW) != 0)
    430 		(*info->fprintf_func) (info->stream, "psw");
    431 
    432 	      else if ((operand->flags & MN10300_OPERAND_MDR) != 0)
    433 		(*info->fprintf_func) (info->stream, "mdr");
    434 
    435 	      else if ((operand->flags & MN10300_OPERAND_RREG) != 0)
    436 		{
    437 		  value = ((insn >> (operand->shift + extra_shift))
    438 			   & ((1 << operand->bits) - 1));
    439 		  if (value < 8)
    440 		    (*info->fprintf_func) (info->stream, "r%d", (int) value);
    441 		  else if (value < 12)
    442 		    (*info->fprintf_func) (info->stream, "a%d", (int) value - 8);
    443 		  else
    444 		    (*info->fprintf_func) (info->stream, "d%d", (int) value - 12);
    445 		}
    446 
    447 	      else if ((operand->flags & MN10300_OPERAND_XRREG) != 0)
    448 		{
    449 		  value = ((insn >> (operand->shift + extra_shift))
    450 			   & ((1 << operand->bits) - 1));
    451 		  if (value == 0)
    452 		    (*info->fprintf_func) (info->stream, "sp");
    453 		  else
    454 		    (*info->fprintf_func) (info->stream, "xr%d", (int) value);
    455 		}
    456 
    457 	      else if ((operand->flags & MN10300_OPERAND_FSREG) != 0)
    458 		(*info->fprintf_func) (info->stream, "fs%d", (int) value);
    459 
    460 	      else if ((operand->flags & MN10300_OPERAND_FDREG) != 0)
    461 		(*info->fprintf_func) (info->stream, "fd%d", (int) value);
    462 
    463 	      else if ((operand->flags & MN10300_OPERAND_FPCR) != 0)
    464 		(*info->fprintf_func) (info->stream, "fpcr");
    465 
    466 	      else if ((operand->flags & MN10300_OPERAND_USP) != 0)
    467 		(*info->fprintf_func) (info->stream, "usp");
    468 
    469 	      else if ((operand->flags & MN10300_OPERAND_SSP) != 0)
    470 		(*info->fprintf_func) (info->stream, "ssp");
    471 
    472 	      else if ((operand->flags & MN10300_OPERAND_MSP) != 0)
    473 		(*info->fprintf_func) (info->stream, "msp");
    474 
    475 	      else if ((operand->flags & MN10300_OPERAND_PC) != 0)
    476 		(*info->fprintf_func) (info->stream, "pc");
    477 
    478 	      else if ((operand->flags & MN10300_OPERAND_EPSW) != 0)
    479 		(*info->fprintf_func) (info->stream, "epsw");
    480 
    481 	      else if ((operand->flags & MN10300_OPERAND_PLUS) != 0)
    482 		(*info->fprintf_func) (info->stream, "+");
    483 
    484 	      else if ((operand->flags & MN10300_OPERAND_PAREN) != 0)
    485 		{
    486 		  if (paren)
    487 		    (*info->fprintf_func) (info->stream, ")");
    488 		  else
    489 		    {
    490 		      (*info->fprintf_func) (info->stream, "(");
    491 		      nocomma = 1;
    492 		    }
    493 		  paren = !paren;
    494 		}
    495 
    496 	      else if ((operand->flags & MN10300_OPERAND_PCREL) != 0)
    497 		(*info->print_address_func) ((long) value + memaddr, info);
    498 
    499 	      else if ((operand->flags & MN10300_OPERAND_MEMADDR) != 0)
    500 		(*info->print_address_func) (value, info);
    501 
    502 	      else if ((operand->flags & MN10300_OPERAND_REG_LIST) != 0)
    503 		{
    504 		  int comma = 0;
    505 
    506 		  (*info->fprintf_func) (info->stream, "[");
    507 		  if (value & 0x80)
    508 		    {
    509 		      (*info->fprintf_func) (info->stream, "d2");
    510 		      comma = 1;
    511 		    }
    512 
    513 		  if (value & 0x40)
    514 		    {
    515 		      if (comma)
    516 			(*info->fprintf_func) (info->stream, ",");
    517 		      (*info->fprintf_func) (info->stream, "d3");
    518 		      comma = 1;
    519 		    }
    520 
    521 		  if (value & 0x20)
    522 		    {
    523 		      if (comma)
    524 			(*info->fprintf_func) (info->stream, ",");
    525 		      (*info->fprintf_func) (info->stream, "a2");
    526 		      comma = 1;
    527 		    }
    528 
    529 		  if (value & 0x10)
    530 		    {
    531 		      if (comma)
    532 			(*info->fprintf_func) (info->stream, ",");
    533 		      (*info->fprintf_func) (info->stream, "a3");
    534 		      comma = 1;
    535 		    }
    536 
    537 		  if (value & 0x08)
    538 		    {
    539 		      if (comma)
    540 			(*info->fprintf_func) (info->stream, ",");
    541 		      (*info->fprintf_func) (info->stream, "other");
    542 		      comma = 1;
    543 		    }
    544 
    545 		  if (value & 0x04)
    546 		    {
    547 		      if (comma)
    548 			(*info->fprintf_func) (info->stream, ",");
    549 		      (*info->fprintf_func) (info->stream, "exreg0");
    550 		      comma = 1;
    551 		    }
    552 		  if (value & 0x02)
    553 		    {
    554 		      if (comma)
    555 			(*info->fprintf_func) (info->stream, ",");
    556 		      (*info->fprintf_func) (info->stream, "exreg1");
    557 		      comma = 1;
    558 		    }
    559 		  if (value & 0x01)
    560 		    {
    561 		      if (comma)
    562 			(*info->fprintf_func) (info->stream, ",");
    563 		      (*info->fprintf_func) (info->stream, "exother");
    564 		      comma = 1;
    565 		    }
    566 		  (*info->fprintf_func) (info->stream, "]");
    567 		}
    568 
    569 	      else
    570 		(*info->fprintf_func) (info->stream, "%ld", (long) value);
    571 	    }
    572 	  /* All done. */
    573 	  break;
    574 	}
    575       op++;
    576     }
    577 
    578   if (!match)
    579     /* xgettext:c-format */
    580     (*info->fprintf_func) (info->stream, _("unknown\t0x%04lx"), insn);
    581 }
    582 
    583 int
    584 print_insn_mn10300 (bfd_vma memaddr, struct disassemble_info *info)
    585 {
    586   int status;
    587   bfd_byte buffer[4];
    588   unsigned long insn;
    589   unsigned int consume;
    590 
    591   /* First figure out how big the opcode is.  */
    592   status = (*info->read_memory_func) (memaddr, buffer, 1, info);
    593   if (status != 0)
    594     {
    595       (*info->memory_error_func) (status, memaddr, info);
    596       return -1;
    597     }
    598   insn = *(unsigned char *) buffer;
    599 
    600   /* These are one byte insns.  */
    601   if ((insn & 0xf3) == 0x00
    602       || (insn & 0xf0) == 0x10
    603       || (insn & 0xfc) == 0x3c
    604       || (insn & 0xf3) == 0x41
    605       || (insn & 0xf3) == 0x40
    606       || (insn & 0xfc) == 0x50
    607       || (insn & 0xfc) == 0x54
    608       || (insn & 0xf0) == 0x60
    609       || (insn & 0xf0) == 0x70
    610       || ((insn & 0xf0) == 0x80
    611 	  && (insn & 0x0c) >> 2 != (insn & 0x03))
    612       || ((insn & 0xf0) == 0x90
    613 	  && (insn & 0x0c) >> 2 != (insn & 0x03))
    614       || ((insn & 0xf0) == 0xa0
    615 	  && (insn & 0x0c) >> 2 != (insn & 0x03))
    616       || ((insn & 0xf0) == 0xb0
    617 	  && (insn & 0x0c) >> 2 != (insn & 0x03))
    618       || (insn & 0xff) == 0xcb
    619       || (insn & 0xfc) == 0xd0
    620       || (insn & 0xfc) == 0xd4
    621       || (insn & 0xfc) == 0xd8
    622       || (insn & 0xf0) == 0xe0
    623       || (insn & 0xff) == 0xff)
    624     {
    625       consume = 1;
    626     }
    627 
    628   /* These are two byte insns.  */
    629   else if ((insn & 0xf0) == 0x80
    630 	   || (insn & 0xf0) == 0x90
    631 	   || (insn & 0xf0) == 0xa0
    632 	   || (insn & 0xf0) == 0xb0
    633 	   || (insn & 0xfc) == 0x20
    634 	   || (insn & 0xfc) == 0x28
    635 	   || (insn & 0xf3) == 0x43
    636 	   || (insn & 0xf3) == 0x42
    637 	   || (insn & 0xfc) == 0x58
    638 	   || (insn & 0xfc) == 0x5c
    639 	   || ((insn & 0xf0) == 0xc0
    640 	       && (insn & 0xff) != 0xcb
    641 	       && (insn & 0xff) != 0xcc
    642 	       && (insn & 0xff) != 0xcd)
    643 	   || (insn & 0xff) == 0xf0
    644 	   || (insn & 0xff) == 0xf1
    645 	   || (insn & 0xff) == 0xf2
    646 	   || (insn & 0xff) == 0xf3
    647 	   || (insn & 0xff) == 0xf4
    648 	   || (insn & 0xff) == 0xf5
    649 	   || (insn & 0xff) == 0xf6)
    650     {
    651       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
    652       if (status != 0)
    653 	{
    654 	  (*info->memory_error_func) (status, memaddr, info);
    655 	  return -1;
    656 	}
    657       insn = bfd_getb16 (buffer);
    658       consume = 2;
    659     }
    660 
    661   /* These are three byte insns.  */
    662   else if ((insn & 0xff) == 0xf8
    663 	   || (insn & 0xff) == 0xcc
    664 	   || (insn & 0xff) == 0xf9
    665 	   || (insn & 0xf3) == 0x01
    666 	   || (insn & 0xf3) == 0x02
    667 	   || (insn & 0xf3) == 0x03
    668 	   || (insn & 0xfc) == 0x24
    669 	   || (insn & 0xfc) == 0x2c
    670 	   || (insn & 0xfc) == 0x30
    671 	   || (insn & 0xfc) == 0x34
    672 	   || (insn & 0xfc) == 0x38
    673 	   || (insn & 0xff) == 0xde
    674 	   || (insn & 0xff) == 0xdf
    675 	   || (insn & 0xff) == 0xf9
    676 	   || (insn & 0xff) == 0xcc)
    677     {
    678       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
    679       if (status != 0)
    680 	{
    681 	  (*info->memory_error_func) (status, memaddr, info);
    682 	  return -1;
    683 	}
    684       insn = bfd_getb16 (buffer);
    685       insn <<= 8;
    686       status = (*info->read_memory_func) (memaddr + 2, buffer, 1, info);
    687       if (status != 0)
    688 	{
    689 	  (*info->memory_error_func) (status, memaddr, info);
    690 	  return -1;
    691 	}
    692       insn |= *(unsigned char *) buffer;
    693       consume = 3;
    694     }
    695 
    696   /* These are four byte insns.  */
    697   else if ((insn & 0xff) == 0xfa
    698 	   || (insn & 0xff) == 0xf7
    699 	   || (insn & 0xff) == 0xfb)
    700     {
    701       status = (*info->read_memory_func) (memaddr, buffer, 4, info);
    702       if (status != 0)
    703 	{
    704 	  (*info->memory_error_func) (status, memaddr, info);
    705 	  return -1;
    706 	}
    707       insn = bfd_getb32 (buffer);
    708       consume = 4;
    709     }
    710 
    711   /* These are five byte insns.  */
    712   else if ((insn & 0xff) == 0xcd
    713 	   || (insn & 0xff) == 0xdc)
    714     {
    715       status = (*info->read_memory_func) (memaddr, buffer, 4, info);
    716       if (status != 0)
    717 	{
    718 	  (*info->memory_error_func) (status, memaddr, info);
    719 	  return -1;
    720 	}
    721       insn = bfd_getb32 (buffer);
    722       consume = 5;
    723     }
    724 
    725   /* These are six byte insns.  */
    726   else if ((insn & 0xff) == 0xfd
    727 	   || (insn & 0xff) == 0xfc)
    728     {
    729       status = (*info->read_memory_func) (memaddr, buffer, 4, info);
    730       if (status != 0)
    731 	{
    732 	  (*info->memory_error_func) (status, memaddr, info);
    733 	  return -1;
    734 	}
    735 
    736       insn = bfd_getb32 (buffer);
    737       consume = 6;
    738     }
    739 
    740   /* Else its a seven byte insns (in theory).  */
    741   else
    742     {
    743       status = (*info->read_memory_func) (memaddr, buffer, 4, info);
    744       if (status != 0)
    745 	{
    746 	  (*info->memory_error_func) (status, memaddr, info);
    747 	  return -1;
    748 	}
    749 
    750       insn = bfd_getb32 (buffer);
    751       consume = 7;
    752       /* Handle the 5-byte extended instruction codes.  */
    753       if ((insn & 0xfff80000) == 0xfe800000)
    754 	consume = 5;
    755     }
    756 
    757   disassemble (memaddr, info, insn, consume);
    758 
    759   return consume;
    760 }
    761