Home | History | Annotate | Line # | Download | only in opcodes
m10300-dis.c revision 1.1.1.8
      1 /* Disassemble MN10300 instructions.
      2    Copyright (C) 1996-2025 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 "disassemble.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_DREG) != 0
    322 		  || (operand->flags & MN10300_OPERAND_AREG) != 0
    323 		  || (operand->flags & MN10300_OPERAND_RREG) != 0
    324 		  || (operand->flags & MN10300_OPERAND_XRREG) != 0)
    325 		value = ((insn >> (operand->shift + extra_shift))
    326 			 & ((1 << operand->bits) - 1));
    327 	      else if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
    328 		{
    329 		  unsigned long temp;
    330 
    331 		  value = insn & ((1 << operand->bits) - 1);
    332 		  value <<= (32 - operand->bits);
    333 		  temp = extension >> operand->shift;
    334 		  temp &= ((1 << (32 - operand->bits)) - 1);
    335 		  value |= temp;
    336 		  value = ((value ^ (((unsigned long) 1) << 31))
    337 			   - (((unsigned long) 1) << 31));
    338 		}
    339 	      else if ((operand->flags & MN10300_OPERAND_24BIT) != 0)
    340 		{
    341 		  unsigned long temp;
    342 
    343 		  value = insn & ((1 << operand->bits) - 1);
    344 		  value <<= (24 - operand->bits);
    345 		  temp = extension >> operand->shift;
    346 		  temp &= ((1 << (24 - operand->bits)) - 1);
    347 		  value |= temp;
    348 		  if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
    349 		    value = ((value & 0xffffff) ^ 0x800000) - 0x800000;
    350 		}
    351 	      else if ((operand->flags & (MN10300_OPERAND_FSREG
    352 					  | MN10300_OPERAND_FDREG)))
    353 		{
    354 		  /* See m10300-opc.c just before #define FSM0 for an
    355 		     explanation of these variables.  Note that
    356 		     FMT-implied shifts are not taken into account for
    357 		     FP registers.  */
    358 		  unsigned long mask_low, mask_high;
    359 		  int shl_low, shr_high, shl_high;
    360 
    361 		  switch (operand->bits)
    362 		    {
    363 		    case 5:
    364 		      /* Handle regular FP registers.  */
    365 		      if (operand->shift >= 0)
    366 			{
    367 			  /* This is an `m' register.  */
    368 			  shl_low = operand->shift;
    369 			  shl_high = 8 + (8 & shl_low) + (shl_low & 4) / 4;
    370 			}
    371 		      else
    372 			{
    373 			  /* This is an `n' register.  */
    374 			  shl_low = -operand->shift;
    375 			  shl_high = shl_low / 4;
    376 			}
    377 		      mask_low = 0x0f;
    378 		      mask_high = 0x10;
    379 		      shr_high = 4;
    380 		      break;
    381 
    382 		    case 3:
    383 		      /* Handle accumulators.  */
    384 		      shl_low = -operand->shift;
    385 		      shl_high = 0;
    386 		      mask_low = 0x03;
    387 		      mask_high = 0x04;
    388 		      shr_high = 2;
    389 		      break;
    390 
    391 		    default:
    392 		      abort ();
    393 		    }
    394 		  value = ((((insn >> shl_high) << shr_high) & mask_high)
    395 			   | ((insn >> shl_low) & mask_low));
    396 		}
    397 	      else if ((operand->flags & MN10300_OPERAND_EXTENDED) != 0)
    398 		value = ((extension >> (operand->shift))
    399 			 & ((1 << operand->bits) - 1));
    400 
    401 	      else
    402 		value = ((insn >> (operand->shift))
    403 			 & ((1 << operand->bits) - 1));
    404 
    405 	      if ((operand->flags & MN10300_OPERAND_SIGNED) != 0
    406 		  /* These are properly extended by the code above.  */
    407 		  && ((operand->flags & MN10300_OPERAND_24BIT) == 0))
    408 		value = ((value ^ (((unsigned long) 1) << (operand->bits - 1)))
    409 			 - (((unsigned long) 1) << (operand->bits - 1)));
    410 
    411 	      if (!nocomma
    412 		  && (!paren
    413 		      || ((operand->flags & MN10300_OPERAND_PAREN) == 0)))
    414 		(*info->fprintf_func) (info->stream, ",");
    415 
    416 	      nocomma = 0;
    417 
    418 	      if ((operand->flags & MN10300_OPERAND_DREG) != 0)
    419 		(*info->fprintf_func) (info->stream, "d%d", (int) value);
    420 
    421 	      else if ((operand->flags & MN10300_OPERAND_AREG) != 0)
    422 		(*info->fprintf_func) (info->stream, "a%d", (int) value);
    423 
    424 	      else if ((operand->flags & MN10300_OPERAND_SP) != 0)
    425 		(*info->fprintf_func) (info->stream, "sp");
    426 
    427 	      else if ((operand->flags & MN10300_OPERAND_PSW) != 0)
    428 		(*info->fprintf_func) (info->stream, "psw");
    429 
    430 	      else if ((operand->flags & MN10300_OPERAND_MDR) != 0)
    431 		(*info->fprintf_func) (info->stream, "mdr");
    432 
    433 	      else if ((operand->flags & MN10300_OPERAND_RREG) != 0)
    434 		{
    435 		  if (value < 8)
    436 		    (*info->fprintf_func) (info->stream, "r%d", (int) value);
    437 		  else if (value < 12)
    438 		    (*info->fprintf_func) (info->stream, "a%d", (int) value - 8);
    439 		  else
    440 		    (*info->fprintf_func) (info->stream, "d%d", (int) value - 12);
    441 		}
    442 
    443 	      else if ((operand->flags & MN10300_OPERAND_XRREG) != 0)
    444 		{
    445 		  if (value == 0)
    446 		    (*info->fprintf_func) (info->stream, "sp");
    447 		  else
    448 		    (*info->fprintf_func) (info->stream, "xr%d", (int) value);
    449 		}
    450 
    451 	      else if ((operand->flags & MN10300_OPERAND_FSREG) != 0)
    452 		(*info->fprintf_func) (info->stream, "fs%d", (int) value);
    453 
    454 	      else if ((operand->flags & MN10300_OPERAND_FDREG) != 0)
    455 		(*info->fprintf_func) (info->stream, "fd%d", (int) value);
    456 
    457 	      else if ((operand->flags & MN10300_OPERAND_FPCR) != 0)
    458 		(*info->fprintf_func) (info->stream, "fpcr");
    459 
    460 	      else if ((operand->flags & MN10300_OPERAND_USP) != 0)
    461 		(*info->fprintf_func) (info->stream, "usp");
    462 
    463 	      else if ((operand->flags & MN10300_OPERAND_SSP) != 0)
    464 		(*info->fprintf_func) (info->stream, "ssp");
    465 
    466 	      else if ((operand->flags & MN10300_OPERAND_MSP) != 0)
    467 		(*info->fprintf_func) (info->stream, "msp");
    468 
    469 	      else if ((operand->flags & MN10300_OPERAND_PC) != 0)
    470 		(*info->fprintf_func) (info->stream, "pc");
    471 
    472 	      else if ((operand->flags & MN10300_OPERAND_EPSW) != 0)
    473 		(*info->fprintf_func) (info->stream, "epsw");
    474 
    475 	      else if ((operand->flags & MN10300_OPERAND_PLUS) != 0)
    476 		(*info->fprintf_func) (info->stream, "+");
    477 
    478 	      else if ((operand->flags & MN10300_OPERAND_PAREN) != 0)
    479 		{
    480 		  if (paren)
    481 		    (*info->fprintf_func) (info->stream, ")");
    482 		  else
    483 		    {
    484 		      (*info->fprintf_func) (info->stream, "(");
    485 		      nocomma = 1;
    486 		    }
    487 		  paren = !paren;
    488 		}
    489 
    490 	      else if ((operand->flags & MN10300_OPERAND_PCREL) != 0)
    491 		(*info->print_address_func) ((long) value + memaddr, info);
    492 
    493 	      else if ((operand->flags & MN10300_OPERAND_MEMADDR) != 0)
    494 		(*info->print_address_func) (value, info);
    495 
    496 	      else if ((operand->flags & MN10300_OPERAND_REG_LIST) != 0)
    497 		{
    498 		  int comma = 0;
    499 
    500 		  (*info->fprintf_func) (info->stream, "[");
    501 		  if (value & 0x80)
    502 		    {
    503 		      (*info->fprintf_func) (info->stream, "d2");
    504 		      comma = 1;
    505 		    }
    506 
    507 		  if (value & 0x40)
    508 		    {
    509 		      if (comma)
    510 			(*info->fprintf_func) (info->stream, ",");
    511 		      (*info->fprintf_func) (info->stream, "d3");
    512 		      comma = 1;
    513 		    }
    514 
    515 		  if (value & 0x20)
    516 		    {
    517 		      if (comma)
    518 			(*info->fprintf_func) (info->stream, ",");
    519 		      (*info->fprintf_func) (info->stream, "a2");
    520 		      comma = 1;
    521 		    }
    522 
    523 		  if (value & 0x10)
    524 		    {
    525 		      if (comma)
    526 			(*info->fprintf_func) (info->stream, ",");
    527 		      (*info->fprintf_func) (info->stream, "a3");
    528 		      comma = 1;
    529 		    }
    530 
    531 		  if (value & 0x08)
    532 		    {
    533 		      if (comma)
    534 			(*info->fprintf_func) (info->stream, ",");
    535 		      (*info->fprintf_func) (info->stream, "other");
    536 		      comma = 1;
    537 		    }
    538 
    539 		  if (value & 0x04)
    540 		    {
    541 		      if (comma)
    542 			(*info->fprintf_func) (info->stream, ",");
    543 		      (*info->fprintf_func) (info->stream, "exreg0");
    544 		      comma = 1;
    545 		    }
    546 		  if (value & 0x02)
    547 		    {
    548 		      if (comma)
    549 			(*info->fprintf_func) (info->stream, ",");
    550 		      (*info->fprintf_func) (info->stream, "exreg1");
    551 		      comma = 1;
    552 		    }
    553 		  if (value & 0x01)
    554 		    {
    555 		      if (comma)
    556 			(*info->fprintf_func) (info->stream, ",");
    557 		      (*info->fprintf_func) (info->stream, "exother");
    558 		      comma = 1;
    559 		    }
    560 		  (*info->fprintf_func) (info->stream, "]");
    561 		}
    562 
    563 	      else
    564 		(*info->fprintf_func) (info->stream, "%ld", (long) value);
    565 	    }
    566 	  /* All done. */
    567 	  break;
    568 	}
    569       op++;
    570     }
    571 
    572   if (!match)
    573     /* xgettext:c-format */
    574     (*info->fprintf_func) (info->stream, _("unknown\t0x%04lx"), insn);
    575 }
    576 
    577 int
    578 print_insn_mn10300 (bfd_vma memaddr, struct disassemble_info *info)
    579 {
    580   int status;
    581   bfd_byte buffer[4];
    582   unsigned long insn;
    583   unsigned int consume;
    584 
    585   /* First figure out how big the opcode is.  */
    586   status = (*info->read_memory_func) (memaddr, buffer, 1, info);
    587   if (status != 0)
    588     {
    589       (*info->memory_error_func) (status, memaddr, info);
    590       return -1;
    591     }
    592   insn = *(unsigned char *) buffer;
    593 
    594   /* These are one byte insns.  */
    595   if ((insn & 0xf3) == 0x00
    596       || (insn & 0xf0) == 0x10
    597       || (insn & 0xfc) == 0x3c
    598       || (insn & 0xf3) == 0x41
    599       || (insn & 0xf3) == 0x40
    600       || (insn & 0xfc) == 0x50
    601       || (insn & 0xfc) == 0x54
    602       || (insn & 0xf0) == 0x60
    603       || (insn & 0xf0) == 0x70
    604       || ((insn & 0xf0) == 0x80
    605 	  && (insn & 0x0c) >> 2 != (insn & 0x03))
    606       || ((insn & 0xf0) == 0x90
    607 	  && (insn & 0x0c) >> 2 != (insn & 0x03))
    608       || ((insn & 0xf0) == 0xa0
    609 	  && (insn & 0x0c) >> 2 != (insn & 0x03))
    610       || ((insn & 0xf0) == 0xb0
    611 	  && (insn & 0x0c) >> 2 != (insn & 0x03))
    612       || (insn & 0xff) == 0xcb
    613       || (insn & 0xfc) == 0xd0
    614       || (insn & 0xfc) == 0xd4
    615       || (insn & 0xfc) == 0xd8
    616       || (insn & 0xf0) == 0xe0
    617       || (insn & 0xff) == 0xff)
    618     {
    619       consume = 1;
    620     }
    621 
    622   /* These are two byte insns.  */
    623   else if ((insn & 0xf0) == 0x80
    624 	   || (insn & 0xf0) == 0x90
    625 	   || (insn & 0xf0) == 0xa0
    626 	   || (insn & 0xf0) == 0xb0
    627 	   || (insn & 0xfc) == 0x20
    628 	   || (insn & 0xfc) == 0x28
    629 	   || (insn & 0xf3) == 0x43
    630 	   || (insn & 0xf3) == 0x42
    631 	   || (insn & 0xfc) == 0x58
    632 	   || (insn & 0xfc) == 0x5c
    633 	   || ((insn & 0xf0) == 0xc0
    634 	       && (insn & 0xff) != 0xcb
    635 	       && (insn & 0xff) != 0xcc
    636 	       && (insn & 0xff) != 0xcd)
    637 	   || (insn & 0xff) == 0xf0
    638 	   || (insn & 0xff) == 0xf1
    639 	   || (insn & 0xff) == 0xf2
    640 	   || (insn & 0xff) == 0xf3
    641 	   || (insn & 0xff) == 0xf4
    642 	   || (insn & 0xff) == 0xf5
    643 	   || (insn & 0xff) == 0xf6)
    644     {
    645       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
    646       if (status != 0)
    647 	{
    648 	  (*info->memory_error_func) (status, memaddr, info);
    649 	  return -1;
    650 	}
    651       insn = bfd_getb16 (buffer);
    652       consume = 2;
    653     }
    654 
    655   /* These are three byte insns.  */
    656   else if ((insn & 0xff) == 0xf8
    657 	   || (insn & 0xff) == 0xcc
    658 	   || (insn & 0xff) == 0xf9
    659 	   || (insn & 0xf3) == 0x01
    660 	   || (insn & 0xf3) == 0x02
    661 	   || (insn & 0xf3) == 0x03
    662 	   || (insn & 0xfc) == 0x24
    663 	   || (insn & 0xfc) == 0x2c
    664 	   || (insn & 0xfc) == 0x30
    665 	   || (insn & 0xfc) == 0x34
    666 	   || (insn & 0xfc) == 0x38
    667 	   || (insn & 0xff) == 0xde
    668 	   || (insn & 0xff) == 0xdf
    669 	   || (insn & 0xff) == 0xf9
    670 	   || (insn & 0xff) == 0xcc)
    671     {
    672       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
    673       if (status != 0)
    674 	{
    675 	  (*info->memory_error_func) (status, memaddr, info);
    676 	  return -1;
    677 	}
    678       insn = bfd_getb16 (buffer);
    679       insn <<= 8;
    680       status = (*info->read_memory_func) (memaddr + 2, buffer, 1, info);
    681       if (status != 0)
    682 	{
    683 	  (*info->memory_error_func) (status, memaddr, info);
    684 	  return -1;
    685 	}
    686       insn |= *(unsigned char *) buffer;
    687       consume = 3;
    688     }
    689 
    690   /* These are four byte insns.  */
    691   else if ((insn & 0xff) == 0xfa
    692 	   || (insn & 0xff) == 0xf7
    693 	   || (insn & 0xff) == 0xfb)
    694     {
    695       status = (*info->read_memory_func) (memaddr, buffer, 4, info);
    696       if (status != 0)
    697 	{
    698 	  (*info->memory_error_func) (status, memaddr, info);
    699 	  return -1;
    700 	}
    701       insn = bfd_getb32 (buffer);
    702       consume = 4;
    703     }
    704 
    705   /* These are five byte insns.  */
    706   else if ((insn & 0xff) == 0xcd
    707 	   || (insn & 0xff) == 0xdc)
    708     {
    709       status = (*info->read_memory_func) (memaddr, buffer, 4, info);
    710       if (status != 0)
    711 	{
    712 	  (*info->memory_error_func) (status, memaddr, info);
    713 	  return -1;
    714 	}
    715       insn = bfd_getb32 (buffer);
    716       consume = 5;
    717     }
    718 
    719   /* These are six byte insns.  */
    720   else if ((insn & 0xff) == 0xfd
    721 	   || (insn & 0xff) == 0xfc)
    722     {
    723       status = (*info->read_memory_func) (memaddr, buffer, 4, info);
    724       if (status != 0)
    725 	{
    726 	  (*info->memory_error_func) (status, memaddr, info);
    727 	  return -1;
    728 	}
    729 
    730       insn = bfd_getb32 (buffer);
    731       consume = 6;
    732     }
    733 
    734   /* Else its a seven byte insns (in theory).  */
    735   else
    736     {
    737       status = (*info->read_memory_func) (memaddr, buffer, 4, info);
    738       if (status != 0)
    739 	{
    740 	  (*info->memory_error_func) (status, memaddr, info);
    741 	  return -1;
    742 	}
    743 
    744       insn = bfd_getb32 (buffer);
    745       consume = 7;
    746       /* Handle the 5-byte extended instruction codes.  */
    747       if ((insn & 0xfff80000) == 0xfe800000)
    748 	consume = 5;
    749     }
    750 
    751   disassemble (memaddr, info, insn, consume);
    752 
    753   return consume;
    754 }
    755