Home | History | Annotate | Line # | Download | only in opcodes
s12z-dis.c revision 1.1.1.1
      1 /* s12z-dis.c -- Freescale S12Z disassembly
      2    Copyright (C) 2018 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 <stdint.h>
     24 #include <stdbool.h>
     25 #include <assert.h>
     26 
     27 #include "s12z.h"
     28 
     29 #include "bfd.h"
     30 #include "dis-asm.h"
     31 
     32 
     33 #include "disassemble.h"
     34 
     35 static int
     36 read_memory (bfd_vma memaddr, bfd_byte* buffer, int size,
     37              struct disassemble_info* info)
     38 {
     39   int status = (*info->read_memory_func) (memaddr, buffer, size, info);
     40   if (status != 0)
     41     {
     42       (*info->memory_error_func) (status, memaddr, info);
     43       return -1;
     44     }
     45   return 0;
     46 }
     47 
     48 typedef int (* insn_bytes_f) (bfd_vma memaddr,
     49 			      struct disassemble_info* info);
     50 
     51 typedef void (*operands_f) (bfd_vma memaddr, struct disassemble_info* info);
     52 
     53 enum OPR_MODE
     54   {
     55     OPR_IMMe4,
     56     OPR_REG,
     57     OPR_OFXYS,
     58     OPR_XY_PRE_INC,
     59     OPR_XY_POST_INC,
     60     OPR_XY_PRE_DEC,
     61     OPR_XY_POST_DEC,
     62     OPR_S_PRE_DEC,
     63     OPR_S_POST_INC,
     64     OPR_REG_DIRECT,
     65     OPR_REG_INDIRECT,
     66     OPR_IDX_DIRECT,
     67     OPR_IDX_INDIRECT,
     68     OPR_EXT1,
     69     OPR_IDX2_REG,
     70     OPR_IDX3_DIRECT,
     71     OPR_IDX3_INDIRECT,
     72 
     73     OPR_EXT18,
     74     OPR_IDX3_DIRECT_REG,
     75     OPR_EXT3_DIRECT,
     76     OPR_EXT3_INDIRECT
     77   };
     78 
     79 struct opr_pb
     80 {
     81   uint8_t mask;
     82   uint8_t value;
     83   int n_operands;
     84   enum OPR_MODE mode;
     85 };
     86 
     87 static const  struct opr_pb opr_pb[] = {
     88   {0xF0, 0x70, 1, OPR_IMMe4},
     89   {0xF8, 0xB8, 1, OPR_REG},
     90   {0xC0, 0x40, 1, OPR_OFXYS},
     91   {0xEF, 0xE3, 1, OPR_XY_PRE_INC},
     92   {0xEF, 0xE7, 1, OPR_XY_POST_INC},
     93   {0xEF, 0xC3, 1, OPR_XY_PRE_DEC},
     94   {0xEF, 0xC7, 1, OPR_XY_POST_DEC},
     95   {0xFF, 0xFB, 1, OPR_S_PRE_DEC},
     96   {0xFF, 0xFF, 1, OPR_S_POST_INC},
     97   {0xC8, 0x88, 1, OPR_REG_DIRECT},
     98   {0xE8, 0xC8, 1, OPR_REG_INDIRECT},
     99 
    100   {0xCE, 0xC0, 2, OPR_IDX_DIRECT},
    101   {0xCE, 0xC4, 2, OPR_IDX_INDIRECT},
    102   {0xC0, 0x00, 2, OPR_EXT1},
    103 
    104   {0xC8, 0x80, 3, OPR_IDX2_REG},
    105   {0xFA, 0xF8, 3, OPR_EXT18},
    106 
    107   {0xCF, 0xC2, 4, OPR_IDX3_DIRECT},
    108   {0xCF, 0xC6, 4, OPR_IDX3_INDIRECT},
    109 
    110   {0xF8, 0xE8, 4, OPR_IDX3_DIRECT_REG},
    111   {0xFF, 0xFA, 4, OPR_EXT3_DIRECT},
    112   {0xFF, 0xFE, 4, OPR_EXT3_INDIRECT},
    113 };
    114 
    115 
    116 /* Return the number of bytes in a OPR operand, including the XB postbyte.
    117    It does not include any preceeding opcodes. */
    118 static int
    119 opr_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
    120 {
    121   bfd_byte xb;
    122   int status = read_memory (memaddr, &xb, 1, info);
    123   if (status < 0)
    124     return status;
    125 
    126   size_t i;
    127   for (i = 0; i < sizeof (opr_pb) / sizeof (opr_pb[0]); ++i)
    128     {
    129       const struct opr_pb *pb = opr_pb + i;
    130       if ((xb & pb->mask) == pb->value)
    131 	{
    132 	  return pb->n_operands;
    133 	}
    134     }
    135 
    136   return 1;
    137 }
    138 
    139 static int
    140 opr_n_bytes_p1 (bfd_vma memaddr, struct disassemble_info* info)
    141 {
    142   return 1 + opr_n_bytes (memaddr, info);
    143 }
    144 
    145 static int
    146 opr_n_bytes2 (bfd_vma memaddr, struct disassemble_info* info)
    147 {
    148   int s = opr_n_bytes (memaddr, info);
    149   s += opr_n_bytes (memaddr + s, info);
    150   return s + 1;
    151 }
    152 
    153 enum BB_MODE
    154   {
    155     BB_REG_REG_REG,
    156     BB_REG_REG_IMM,
    157     BB_REG_OPR_REG,
    158     BB_OPR_REG_REG,
    159     BB_REG_OPR_IMM,
    160     BB_OPR_REG_IMM
    161   };
    162 
    163 struct opr_bb
    164 {
    165   uint8_t mask;
    166   uint8_t value;
    167   int n_operands;
    168   bool opr;
    169   enum BB_MODE mode;
    170 };
    171 
    172 static const struct opr_bb bb_modes[] =
    173   {
    174     {0x60, 0x00, 2, false, BB_REG_REG_REG},
    175     {0x60, 0x20, 3, false, BB_REG_REG_IMM},
    176     {0x70, 0x40, 2, true,  BB_REG_OPR_REG},
    177     {0x70, 0x50, 2, true,  BB_OPR_REG_REG},
    178     {0x70, 0x60, 3, true,  BB_REG_OPR_IMM},
    179     {0x70, 0x70, 3, true,  BB_OPR_REG_IMM}
    180   };
    181 
    182 static int
    183 bfextins_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
    184 {
    185   bfd_byte bb;
    186   int status = read_memory (memaddr, &bb, 1, info);
    187   if (status < 0)
    188     return status;
    189 
    190   size_t i;
    191   const struct opr_bb *bbs = 0;
    192   for (i = 0; i < sizeof (bb_modes) / sizeof (bb_modes[0]); ++i)
    193     {
    194       bbs = bb_modes + i;
    195       if ((bb & bbs->mask) == bbs->value)
    196 	{
    197 	  break;
    198 	}
    199     }
    200 
    201   int n = bbs->n_operands;
    202   if (bbs->opr)
    203     n += opr_n_bytes (memaddr + n - 1, info);
    204 
    205   return n;
    206 }
    207 
    208 static int
    209 single (bfd_vma memaddr ATTRIBUTE_UNUSED,
    210 	struct disassemble_info* info ATTRIBUTE_UNUSED)
    211 {
    212   return 1;
    213 }
    214 
    215 static int
    216 two (bfd_vma memaddr ATTRIBUTE_UNUSED,
    217      struct disassemble_info* info ATTRIBUTE_UNUSED)
    218 {
    219   return 2;
    220 }
    221 
    222 static int
    223 three (bfd_vma memaddr ATTRIBUTE_UNUSED,
    224        struct disassemble_info* info ATTRIBUTE_UNUSED)
    225 {
    226   return 3;
    227 }
    228 
    229 static int
    230 four (bfd_vma memaddr ATTRIBUTE_UNUSED,
    231       struct disassemble_info* info ATTRIBUTE_UNUSED)
    232 {
    233   return 4;
    234 }
    235 
    236 static int
    237 five (bfd_vma memaddr ATTRIBUTE_UNUSED,
    238       struct disassemble_info* info ATTRIBUTE_UNUSED)
    239 {
    240   return 5;
    241 }
    242 
    243 static int
    244 pcrel_15bit (bfd_vma memaddr, struct disassemble_info* info)
    245 {
    246   bfd_byte byte;
    247   int status = read_memory (memaddr, &byte, 1, info);
    248   if (status < 0)
    249     return status;
    250   return (byte & 0x80) ? 3 : 2;
    251 }
    252 
    253 
    254 
    255 
    257 static void
    258 operand_separator (struct disassemble_info *info)
    259 {
    260   if ((info->flags & 0x2))
    261     {
    262       (*info->fprintf_func) (info->stream, ", ");
    263     }
    264   else
    265     {
    266       (*info->fprintf_func) (info->stream, " ");
    267     }
    268 
    269   info->flags |= 0x2;
    270 }
    271 
    272 
    273 
    275 static void
    276 imm1 (bfd_vma memaddr, struct disassemble_info* info)
    277 {
    278   bfd_byte byte;
    279   int status = read_memory (memaddr, &byte, 1, info);
    280   if (status < 0)
    281     return;
    282 
    283   operand_separator (info);
    284   (*info->fprintf_func) (info->stream, "#%d", byte);
    285 }
    286 
    287 static void
    288 trap_decode (bfd_vma memaddr, struct disassemble_info* info)
    289 {
    290   imm1 (memaddr - 1, info);
    291 }
    292 
    293 
    294 const struct reg registers[S12Z_N_REGISTERS] =
    295   {
    296     {"d2", 2},
    297     {"d3", 2},
    298     {"d4", 2},
    299     {"d5", 2},
    300 
    301     {"d0", 1},
    302     {"d1", 1},
    303 
    304     {"d6", 4},
    305     {"d7", 4},
    306 
    307     {"x", 3},
    308     {"y", 3},
    309     {"s", 3},
    310     {"p", 3},
    311     {"cch", 1},
    312     {"ccl", 1},
    313     {"ccw", 2}
    314   };
    315 
    316 static char *
    317 xys_from_postbyte (uint8_t postbyte)
    318 {
    319   char *reg = "?";
    320   switch ((postbyte & 0x30) >> 4)
    321     {
    322     case 0:
    323       reg = "x";
    324       break;
    325     case 1:
    326       reg = "y";
    327       break;
    328     case 2:
    329       reg = "s";
    330       break;
    331     default:
    332       reg = "?";
    333       break;
    334     }
    335   return reg;
    336 }
    337 
    338 static char *
    339 xysp_from_postbyte (uint8_t postbyte)
    340 {
    341   char *reg = "?";
    342   switch ((postbyte & 0x30) >> 4)
    343     {
    344     case 0:
    345       reg = "x";
    346       break;
    347     case 1:
    348       reg = "y";
    349       break;
    350     case 2:
    351       reg = "s";
    352       break;
    353     default:
    354       reg = "p";
    355       break;
    356     }
    357   return reg;
    358 }
    359 
    360 /* Render the symbol name whose value is ADDR or the adddress itself if there is
    361    no symbol. */
    362 static void
    363 decode_possible_symbol (bfd_vma addr, struct disassemble_info *info)
    364 {
    365   if (!info->symbol_at_address_func (addr, info))
    366     {
    367       (*info->fprintf_func) (info->stream, "%" BFD_VMA_FMT "d", addr);
    368     }
    369   else
    370     {
    371       asymbol *sym = NULL;
    372       int j;
    373       for (j = 0; j < info->symtab_size; ++j)
    374 	{
    375 	  sym = info->symtab[j];
    376 	  if (bfd_asymbol_value (sym) == addr)
    377 	    {
    378 	      break;
    379 	    }
    380 	}
    381       if (j < info->symtab_size)
    382 	(*info->fprintf_func) (info->stream, "%s", bfd_asymbol_name (sym));
    383     }
    384 }
    385 
    386 static void ld_18bit_decode (bfd_vma memaddr, struct disassemble_info* info);
    387 
    388 static void
    389 ext24_decode (bfd_vma memaddr, struct disassemble_info* info)
    390 {
    391   uint8_t buffer[3];
    392   int status = read_memory (memaddr, buffer, 3, info);
    393   if (status < 0)
    394     return;
    395 
    396   int i;
    397   uint32_t addr = 0;
    398   for (i = 0; i < 3; ++i)
    399     {
    400       addr <<= 8;
    401       addr |= buffer[i];
    402     }
    403 
    404   operand_separator (info);
    405   decode_possible_symbol (addr, info);
    406 }
    407 
    408 
    409 static uint32_t
    410 decode_signed_value (bfd_vma memaddr, struct disassemble_info* info, short size)
    411 {
    412   assert (size >0);
    413   assert (size <= 4);
    414   bfd_byte buffer[4];
    415   if (0 > read_memory (memaddr, buffer, size, info))
    416     {
    417       return 0;
    418     }
    419 
    420   int i;
    421   uint32_t value = 0;
    422   for (i = 0; i < size; ++i)
    423     {
    424       value |= buffer[i] << (8 * (size - i - 1));
    425     }
    426 
    427   if (buffer[0] & 0x80)
    428     {
    429       /* Deal with negative values */
    430       value -= 0x1UL << (size * 8);
    431     }
    432   return value;
    433 }
    434 
    435 
    436 static void
    437 opr_decode (bfd_vma memaddr, struct disassemble_info* info)
    438 {
    439   bfd_byte postbyte;
    440   int status = read_memory (memaddr, &postbyte, 1, info);
    441   if (status < 0)
    442     return;
    443 
    444   enum OPR_MODE mode = -1;
    445   size_t i;
    446   for (i = 0; i < sizeof (opr_pb) / sizeof (opr_pb[0]); ++i)
    447     {
    448       const struct opr_pb *pb = opr_pb + i;
    449       if ((postbyte & pb->mask) == pb->value)
    450 	{
    451 	  mode = pb->mode;
    452 	  break;
    453 	}
    454     }
    455 
    456   operand_separator (info);
    457   switch (mode)
    458     {
    459     case OPR_IMMe4:
    460       {
    461 	int n;
    462 	uint8_t x = (postbyte & 0x0F);
    463 	if (x == 0)
    464 	  n = -1;
    465 	else
    466 	  n = x;
    467 
    468 	(*info->fprintf_func) (info->stream, "#%d", n);
    469 	break;
    470       }
    471     case OPR_REG:
    472       {
    473 	uint8_t x = (postbyte & 0x07);
    474 	(*info->fprintf_func) (info->stream, "%s", registers[x].name);
    475 	break;
    476       }
    477     case OPR_OFXYS:
    478       {
    479 	const char *reg  = xys_from_postbyte (postbyte);
    480 	(*info->fprintf_func) (info->stream, "(%d,%s)", postbyte & 0x0F, reg);
    481 	break;
    482       }
    483     case OPR_REG_DIRECT:
    484       {
    485 	(*info->fprintf_func) (info->stream, "(%s,%s)", registers[postbyte & 0x07].name,
    486 			       xys_from_postbyte (postbyte));
    487 	break;
    488       }
    489     case OPR_REG_INDIRECT:
    490       {
    491 	(*info->fprintf_func) (info->stream, "[%s,%s]", registers[postbyte & 0x07].name,
    492 			       (postbyte & 0x10) ? "y": "x");
    493 	break;
    494       }
    495 
    496     case OPR_IDX_INDIRECT:
    497       {
    498 	uint8_t x1;
    499 	read_memory (memaddr + 1, &x1, 1, info);
    500 	int idx = x1;
    501 
    502 	if (postbyte & 0x01)
    503 	  {
    504 	    /* Deal with negative values */
    505 	    idx -= 0x1UL << 8;
    506 	  }
    507 
    508 	(*info->fprintf_func) (info->stream, "[%d,%s]", idx,
    509 			       xysp_from_postbyte (postbyte));
    510 	break;
    511       }
    512 
    513     case OPR_IDX3_DIRECT:
    514       {
    515 	uint8_t x[3];
    516 	read_memory (memaddr + 1, x, 3, info);
    517 	int idx = x[0] << 16 | x[1] << 8 | x[2];
    518 
    519 	if (x[0] & 0x80)
    520 	  {
    521 	    /* Deal with negative values */
    522 	    idx -= 0x1UL << 24;
    523 	  }
    524 
    525 	(*info->fprintf_func) (info->stream, "(%d,%s)", idx,
    526 			       xysp_from_postbyte (postbyte));
    527 	break;
    528       }
    529 
    530     case OPR_IDX3_DIRECT_REG:
    531       {
    532 	uint8_t x[3];
    533 	read_memory (memaddr + 1, x, 3, info);
    534 	int idx = x[0] << 16 | x[1] << 8 | x[2];
    535 
    536 	if (x[0] & 0x80)
    537 	  {
    538 	    /* Deal with negative values */
    539 	    idx -= 0x1UL << 24;
    540 	  }
    541 
    542 	(*info->fprintf_func) (info->stream, "(%d,%s)", idx,
    543 			       registers[postbyte & 0x07].name);
    544 	break;
    545       }
    546 
    547     case OPR_IDX3_INDIRECT:
    548       {
    549 	uint8_t x[3];
    550 	read_memory (memaddr + 1, x, 3, info);
    551 	int idx = x[0] << 16 | x[1] << 8 | x[2];
    552 
    553 	if (x[0] & 0x80)
    554 	  {
    555 	    /* Deal with negative values */
    556 	    idx -= 0x1UL << 24;
    557 	  }
    558 
    559 	(*info->fprintf_func) (info->stream, "[%d,%s]", idx,
    560 			       xysp_from_postbyte (postbyte));
    561 	break;
    562       }
    563 
    564     case OPR_IDX_DIRECT:
    565       {
    566 	uint8_t x1;
    567 	read_memory (memaddr + 1, &x1, 1, info);
    568 	int idx = x1;
    569 
    570 	if (postbyte & 0x01)
    571 	  {
    572 	    /* Deal with negative values */
    573 	    idx -= 0x1UL << 8;
    574 	  }
    575 
    576 	(*info->fprintf_func) (info->stream, "(%d,%s)", idx,
    577 			       xysp_from_postbyte (postbyte));
    578 	break;
    579       }
    580 
    581     case OPR_IDX2_REG:
    582       {
    583 	uint8_t x[2];
    584 	read_memory (memaddr + 1, x, 2, info);
    585 	uint32_t offset = x[1] | x[0] << 8 ;
    586 	offset |= (postbyte & 0x30) << 12;
    587 
    588 	(*info->fprintf_func) (info->stream, "(%d,%s)", offset,
    589 			       registers[postbyte & 0x07].name);
    590 	break;
    591       }
    592 
    593     case OPR_XY_PRE_INC:
    594       {
    595 	(*info->fprintf_func) (info->stream, "(+%s)",
    596 			       (postbyte & 0x10) ? "y": "x");
    597 
    598 	break;
    599       }
    600     case OPR_XY_POST_INC:
    601       {
    602 	(*info->fprintf_func) (info->stream, "(%s+)",
    603 			       (postbyte & 0x10) ? "y": "x");
    604 
    605 	break;
    606       }
    607     case OPR_XY_PRE_DEC:
    608       {
    609 	(*info->fprintf_func) (info->stream, "(-%s)",
    610 			       (postbyte & 0x10) ? "y": "x");
    611 
    612 	break;
    613       }
    614     case OPR_XY_POST_DEC:
    615       {
    616 	(*info->fprintf_func) (info->stream, "(%s-)",
    617 			       (postbyte & 0x10) ? "y": "x");
    618 
    619 	break;
    620       }
    621     case OPR_S_PRE_DEC:
    622       {
    623 	(*info->fprintf_func) (info->stream, "(-s)");
    624 	break;
    625       }
    626     case OPR_S_POST_INC:
    627       {
    628 	(*info->fprintf_func) (info->stream, "(s+)");
    629 	break;
    630       }
    631 
    632     case OPR_EXT18:
    633       {
    634 	const size_t size = 2;
    635 	bfd_byte buffer[4];
    636 	status = read_memory (memaddr + 1, buffer, size, info);
    637 	if (status < 0)
    638 	  return;
    639 
    640 	uint32_t ext18 = 0;
    641 	for (i = 0; i < size; ++i)
    642 	  {
    643 	    ext18 <<= 8;
    644 	    ext18 |= buffer[i];
    645 	  }
    646 
    647 	ext18 |= (postbyte & 0x01) << 16;
    648 	ext18 |= (postbyte & 0x04) << 15;
    649 
    650 	decode_possible_symbol (ext18, info);
    651 	break;
    652       }
    653 
    654     case OPR_EXT1:
    655       {
    656 	uint8_t x1 = 0;
    657 	read_memory (memaddr + 1, &x1, 1, info);
    658 	int16_t addr;
    659 	addr = x1;
    660 	addr |= (postbyte & 0x3f) << 8;
    661 
    662 	decode_possible_symbol (addr, info);
    663 	break;
    664       }
    665 
    666     case OPR_EXT3_DIRECT:
    667       {
    668 	const size_t size = 3;
    669 	bfd_byte buffer[4];
    670 	status = read_memory (memaddr + 1, buffer, size, info);
    671 	if (status < 0)
    672 	  return;
    673 
    674 	uint32_t ext24 = 0;
    675 	for (i = 0; i < size; ++i)
    676 	  {
    677 	    ext24 |= buffer[i] << (8 * (size - i - 1));
    678 	  }
    679 
    680 	decode_possible_symbol (ext24, info);
    681 	break;
    682       }
    683 
    684     case OPR_EXT3_INDIRECT:
    685       {
    686 	const size_t size = 3;
    687 	bfd_byte buffer[4];
    688 	status = read_memory (memaddr + 1, buffer, size, info);
    689 	if (status < 0)
    690 	  return;
    691 
    692 	uint32_t ext24 = 0;
    693 	for (i = 0; i < size; ++i)
    694 	  {
    695 	    ext24 |= buffer[i] << (8 * (size - i - 1));
    696 	  }
    697 
    698 	(*info->fprintf_func) (info->stream, "[%d]", ext24);
    699 
    700 	break;
    701       }
    702 
    703     default:
    704       (*info->fprintf_func) (info->stream, "Unknown OPR mode #0x%x (%d)", postbyte, mode);
    705     }
    706 }
    707 
    708 
    709 static void
    710 opr_decode2 (bfd_vma memaddr, struct disassemble_info* info)
    711 {
    712   int n = opr_n_bytes (memaddr, info);
    713   opr_decode (memaddr, info);
    714   opr_decode (memaddr + n, info);
    715 }
    716 
    717 static void
    718 imm1234 (bfd_vma memaddr, struct disassemble_info* info, int base)
    719 {
    720   bfd_byte opcode;
    721   int status = read_memory (memaddr - 1, &opcode, 1, info);
    722   if (status < 0)
    723     return;
    724 
    725   opcode -= base;
    726 
    727   int size = registers[opcode & 0xF].bytes;
    728 
    729   uint32_t imm = decode_signed_value (memaddr, info, size);
    730   operand_separator (info);
    731   (*info->fprintf_func) (info->stream, "#%d", imm);
    732 }
    733 
    734 
    735 /* Special case of LD and CMP with register S and IMM operand */
    736 static void
    737 reg_s_imm (bfd_vma memaddr, struct disassemble_info* info)
    738 {
    739   operand_separator (info);
    740   (*info->fprintf_func) (info->stream, "s");
    741 
    742   uint32_t imm = decode_signed_value (memaddr, info, 3);
    743   operand_separator (info);
    744   (*info->fprintf_func) (info->stream, "#%d", imm);
    745 }
    746 
    747 /* Special case of LD, CMP and ST with register S and OPR operand */
    748 static void
    749 reg_s_opr (bfd_vma memaddr, struct disassemble_info* info)
    750 {
    751   operand_separator (info);
    752   (*info->fprintf_func) (info->stream, "s");
    753 
    754   opr_decode (memaddr, info);
    755 }
    756 
    757 static void
    758 imm1234_8base (bfd_vma memaddr, struct disassemble_info* info)
    759 {
    760   imm1234 (memaddr, info, 8);
    761 }
    762 
    763 static void
    764 imm1234_0base (bfd_vma memaddr, struct disassemble_info* info)
    765 {
    766   imm1234 (memaddr, info, 0);
    767 }
    768 
    769 static void
    770 tfr (bfd_vma memaddr, struct disassemble_info* info)
    771 {
    772   bfd_byte byte;
    773   int status = read_memory (memaddr, &byte, 1, info);
    774   if (status < 0)
    775     return;
    776 
    777   operand_separator (info);
    778   (*info->fprintf_func) (info->stream, "%s, %s",
    779 			 registers[byte >> 4].name,
    780 			 registers[byte & 0xF].name);
    781 }
    782 
    783 
    784 static void
    785 reg (bfd_vma memaddr, struct disassemble_info* info)
    786 {
    787   bfd_byte byte;
    788   int status = read_memory (memaddr - 1, &byte, 1, info);
    789   if (status < 0)
    790     return;
    791 
    792   operand_separator (info);
    793   (*info->fprintf_func) (info->stream, "%s", registers[byte & 0x07].name);
    794 }
    795 
    796 static void
    797 reg_xy (bfd_vma memaddr, struct disassemble_info* info)
    798 {
    799   bfd_byte byte;
    800   int status = read_memory (memaddr - 1, &byte, 1, info);
    801   if (status < 0)
    802     return;
    803 
    804   operand_separator (info);
    805   (*info->fprintf_func) (info->stream, "%s", (byte & 0x01) ? "y" : "x");
    806 }
    807 
    808 static void
    809 lea_reg_xys_opr (bfd_vma memaddr, struct disassemble_info* info)
    810 {
    811   bfd_byte byte;
    812   int status = read_memory (memaddr - 1, &byte, 1, info);
    813   if (status < 0)
    814     return;
    815 
    816   char *reg = NULL;
    817   switch (byte & 0x03)
    818     {
    819     case 0x00:
    820       reg = "x";
    821       break;
    822     case 0x01:
    823       reg = "y";
    824       break;
    825     case 0x02:
    826       reg = "s";
    827       break;
    828     }
    829 
    830   operand_separator (info);
    831   (*info->fprintf_func) (info->stream, "%s", reg);
    832   opr_decode (memaddr, info);
    833 }
    834 
    835 
    836 
    837 static void
    838 lea_reg_xys (bfd_vma memaddr, struct disassemble_info* info)
    839 {
    840   bfd_byte byte;
    841   int status = read_memory (memaddr - 1, &byte, 1, info);
    842   if (status < 0)
    843     return;
    844 
    845   char *reg = NULL;
    846   switch (byte & 0x03)
    847     {
    848     case 0x00:
    849       reg = "x";
    850       break;
    851     case 0x01:
    852       reg = "y";
    853       break;
    854     case 0x02:
    855       reg = "s";
    856       break;
    857     }
    858 
    859   status = read_memory (memaddr, &byte, 1, info);
    860   if (status < 0)
    861     return;
    862 
    863   int8_t v = byte;
    864 
    865   operand_separator (info);
    866   (*info->fprintf_func) (info->stream, "%s, (%d,%s)", reg, v, reg);
    867 }
    868 
    869 
    870 /* PC Relative offsets of size 15 or 7 bits */
    871 static void
    872 rel_15_7 (bfd_vma memaddr, struct disassemble_info* info, int offset)
    873 {
    874   bfd_byte upper;
    875   int status = read_memory (memaddr, &upper, 1, info);
    876   if (status < 0)
    877     return;
    878 
    879   bool rel_size = (upper & 0x80);
    880 
    881   int16_t addr = upper;
    882   if (rel_size)
    883     {
    884       /* 15 bits.  Get the next byte */
    885       bfd_byte lower;
    886       status = read_memory (memaddr + 1, &lower, 1, info);
    887       if (status < 0)
    888 	return;
    889 
    890       addr <<= 8;
    891       addr |= lower;
    892       addr &= 0x7FFF;
    893 
    894       bool negative = (addr & 0x4000);
    895       addr &= 0x3FFF;
    896       if (negative)
    897 	addr = addr - 0x4000;
    898     }
    899   else
    900     {
    901       /* 7 bits. */
    902       bool negative = (addr & 0x40);
    903       addr &= 0x3F;
    904       if (negative)
    905 	addr = addr - 0x40;
    906     }
    907 
    908   operand_separator (info);
    909   if (!info->symbol_at_address_func (addr + memaddr - offset, info))
    910     {
    911       (*info->fprintf_func) (info->stream, "*%+d", addr);
    912     }
    913   else
    914     {
    915       asymbol *sym = NULL;
    916       int i;
    917       for (i = 0; i < info->symtab_size; ++i)
    918 	{
    919 	  sym = info->symtab[i];
    920 	  if (bfd_asymbol_value (sym) == addr + memaddr - offset)
    921 	    {
    922 	      break;
    923 	    }
    924 	}
    925       if (i < info->symtab_size)
    926 	(*info->fprintf_func) (info->stream, "%s", bfd_asymbol_name (sym));
    927     }
    928 }
    929 
    930 
    931 /* PC Relative offsets of size 15 or 7 bits */
    932 static void
    933 decode_rel_15_7 (bfd_vma memaddr, struct disassemble_info* info)
    934 {
    935   rel_15_7 (memaddr, info, 1);
    936 }
    937 
    938 struct opcode
    939 {
    940   const char *mnemonic;
    941   insn_bytes_f insn_bytes;
    942   operands_f operands;
    943   operands_f operands2;
    944 };
    945 
    946 static int shift_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
    947 static int mov_imm_opr_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
    948 static int loop_prim_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
    949 static void mov_imm_opr (bfd_vma memaddr, struct disassemble_info* info);
    950 static void bm_rel_decode (bfd_vma memaddr, struct disassemble_info* info);
    951 static int bm_rel_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
    952 static int mul_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
    953 static void mul_decode (bfd_vma memaddr, struct disassemble_info* info);
    954 static int bm_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
    955 static void bm_decode (bfd_vma memaddr, struct disassemble_info* info);
    956 
    957 static void
    958 cmp_xy (bfd_vma memaddr ATTRIBUTE_UNUSED, struct disassemble_info* info)
    959 {
    960   operand_separator (info);
    961   (*info->fprintf_func) (info->stream, "x, y");
    962 }
    963 
    964 static void
    965 sub_d6_x_y (bfd_vma memaddr ATTRIBUTE_UNUSED, struct disassemble_info* info)
    966 {
    967   operand_separator (info);
    968   (*info->fprintf_func) (info->stream, "d6, x, y");
    969 }
    970 
    971 static void
    972 sub_d6_y_x (bfd_vma memaddr ATTRIBUTE_UNUSED, struct disassemble_info* info)
    973 {
    974   operand_separator (info);
    975   (*info->fprintf_func) (info->stream, "d6, y, x");
    976 }
    977 
    978 static const char shift_size_table[] = {
    979   'b', 'w', 'p', 'l'
    980 };
    981 
    982 static const struct opcode page2[] =
    983   {
    984     [0x00] = {"ld",  opr_n_bytes_p1, 0, reg_s_opr},
    985     [0x01] = {"st",  opr_n_bytes_p1, 0, reg_s_opr},
    986     [0x02] = {"cmp", opr_n_bytes_p1, 0, reg_s_opr},
    987     [0x03] = {"ld",  four, 0, reg_s_imm},
    988     [0x04] = {"cmp", four, 0, reg_s_imm},
    989     [0x05] = {"stop", single, 0, 0},
    990     [0x06] = {"wai",  single, 0, 0},
    991     [0x07] = {"sys",  single, 0, 0},
    992     [0x08] = {NULL,  bfextins_n_bytes, 0, 0},  /* BFEXT / BFINS */
    993     [0x09] = {NULL,  bfextins_n_bytes, 0, 0},
    994     [0x0a] = {NULL,  bfextins_n_bytes, 0, 0},
    995     [0x0b] = {NULL,  bfextins_n_bytes, 0, 0},
    996     [0x0c] = {NULL,  bfextins_n_bytes, 0, 0},
    997     [0x0d] = {NULL,  bfextins_n_bytes, 0, 0},
    998     [0x0e] = {NULL,  bfextins_n_bytes, 0, 0},
    999     [0x0f] = {NULL,  bfextins_n_bytes, 0, 0},
   1000     [0x10] = {"minu", opr_n_bytes_p1, reg, opr_decode},
   1001     [0x11] = {"minu", opr_n_bytes_p1, reg, opr_decode},
   1002     [0x12] = {"minu", opr_n_bytes_p1, reg, opr_decode},
   1003     [0x13] = {"minu", opr_n_bytes_p1, reg, opr_decode},
   1004     [0x14] = {"minu", opr_n_bytes_p1, reg, opr_decode},
   1005     [0x15] = {"minu", opr_n_bytes_p1, reg, opr_decode},
   1006     [0x16] = {"minu", opr_n_bytes_p1, reg, opr_decode},
   1007     [0x17] = {"minu", opr_n_bytes_p1, reg, opr_decode},
   1008     [0x18] = {"maxu", opr_n_bytes_p1, reg, opr_decode},
   1009     [0x19] = {"maxu", opr_n_bytes_p1, reg, opr_decode},
   1010     [0x1a] = {"maxu", opr_n_bytes_p1, reg, opr_decode},
   1011     [0x1b] = {"maxu", opr_n_bytes_p1, reg, opr_decode},
   1012     [0x1c] = {"maxu", opr_n_bytes_p1, reg, opr_decode},
   1013     [0x1d] = {"maxu", opr_n_bytes_p1, reg, opr_decode},
   1014     [0x1e] = {"maxu", opr_n_bytes_p1, reg, opr_decode},
   1015     [0x1f] = {"maxu", opr_n_bytes_p1, reg, opr_decode},
   1016     [0x20] = {"mins", opr_n_bytes_p1, reg, opr_decode},
   1017     [0x21] = {"mins", opr_n_bytes_p1, reg, opr_decode},
   1018     [0x22] = {"mins", opr_n_bytes_p1, reg, opr_decode},
   1019     [0x23] = {"mins", opr_n_bytes_p1, reg, opr_decode},
   1020     [0x24] = {"mins", opr_n_bytes_p1, reg, opr_decode},
   1021     [0x25] = {"mins", opr_n_bytes_p1, reg, opr_decode},
   1022     [0x26] = {"mins", opr_n_bytes_p1, reg, opr_decode},
   1023     [0x27] = {"mins", opr_n_bytes_p1, reg, opr_decode},
   1024     [0x28] = {"maxs", opr_n_bytes_p1, reg, opr_decode},
   1025     [0x29] = {"maxs", opr_n_bytes_p1, reg, opr_decode},
   1026     [0x2a] = {"maxs", opr_n_bytes_p1, reg, opr_decode},
   1027     [0x2b] = {"maxs", opr_n_bytes_p1, reg, opr_decode},
   1028     [0x2c] = {"maxs", opr_n_bytes_p1, reg, opr_decode},
   1029     [0x2d] = {"maxs", opr_n_bytes_p1, reg, opr_decode},
   1030     [0x2e] = {"maxs", opr_n_bytes_p1, reg, opr_decode},
   1031     [0x2f] = {"maxs", opr_n_bytes_p1, reg, opr_decode},
   1032     [0x30] = {"div", mul_n_bytes, mul_decode, 0},
   1033     [0x31] = {"div", mul_n_bytes, mul_decode, 0},
   1034     [0x32] = {"div", mul_n_bytes, mul_decode, 0},
   1035     [0x33] = {"div", mul_n_bytes, mul_decode, 0},
   1036     [0x34] = {"div", mul_n_bytes, mul_decode, 0},
   1037     [0x35] = {"div", mul_n_bytes, mul_decode, 0},
   1038     [0x36] = {"div", mul_n_bytes, mul_decode, 0},
   1039     [0x37] = {"div", mul_n_bytes, mul_decode, 0},
   1040     [0x38] = {"mod", mul_n_bytes, mul_decode, 0},
   1041     [0x39] = {"mod", mul_n_bytes, mul_decode, 0},
   1042     [0x3a] = {"mod", mul_n_bytes, mul_decode, 0},
   1043     [0x3b] = {"mod", mul_n_bytes, mul_decode, 0},
   1044     [0x3c] = {"mod", mul_n_bytes, mul_decode, 0},
   1045     [0x3d] = {"mod", mul_n_bytes, mul_decode, 0},
   1046     [0x3e] = {"mod", mul_n_bytes, mul_decode, 0},
   1047     [0x3f] = {"mod", mul_n_bytes, mul_decode, 0},
   1048     [0x40] = {"abs", single, reg, 0},
   1049     [0x41] = {"abs", single, reg, 0},
   1050     [0x42] = {"abs", single, reg, 0},
   1051     [0x43] = {"abs", single, reg, 0},
   1052     [0x44] = {"abs", single, reg, 0},
   1053     [0x45] = {"abs", single, reg, 0},
   1054     [0x46] = {"abs", single, reg, 0},
   1055     [0x47] = {"abs", single, reg, 0},
   1056     [0x48] = {"mac", mul_n_bytes, mul_decode, 0},
   1057     [0x49] = {"mac", mul_n_bytes, mul_decode, 0},
   1058     [0x4a] = {"mac", mul_n_bytes, mul_decode, 0},
   1059     [0x4b] = {"mac", mul_n_bytes, mul_decode, 0},
   1060     [0x4c] = {"mac", mul_n_bytes, mul_decode, 0},
   1061     [0x4d] = {"mac", mul_n_bytes, mul_decode, 0},
   1062     [0x4e] = {"mac", mul_n_bytes, mul_decode, 0},
   1063     [0x4f] = {"mac", mul_n_bytes, mul_decode, 0},
   1064     [0x50] = {"adc", three, reg, imm1234_0base},
   1065     [0x51] = {"adc", three, reg, imm1234_0base},
   1066     [0x52] = {"adc", three, reg, imm1234_0base},
   1067     [0x53] = {"adc", three, reg, imm1234_0base},
   1068     [0x54] = {"adc", two,   reg, imm1234_0base},
   1069     [0x55] = {"adc", two,   reg, imm1234_0base},
   1070     [0x56] = {"adc", five,  reg, imm1234_0base},
   1071     [0x57] = {"adc", five,  reg, imm1234_0base},
   1072     [0x58] = {"bit", three, reg, imm1234_8base},
   1073     [0x59] = {"bit", three, reg, imm1234_8base},
   1074     [0x5a] = {"bit", three, reg, imm1234_8base},
   1075     [0x5b] = {"bit", three, reg, imm1234_8base},
   1076     [0x5c] = {"bit", two,   reg, imm1234_8base},
   1077     [0x5d] = {"bit", two,   reg, imm1234_8base},
   1078     [0x5e] = {"bit", five,  reg, imm1234_8base},
   1079     [0x5f] = {"bit", five,  reg, imm1234_8base},
   1080     [0x60] = {"adc", opr_n_bytes_p1, reg, opr_decode},
   1081     [0x61] = {"adc", opr_n_bytes_p1, reg, opr_decode},
   1082     [0x62] = {"adc", opr_n_bytes_p1, reg, opr_decode},
   1083     [0x63] = {"adc", opr_n_bytes_p1, reg, opr_decode},
   1084     [0x64] = {"adc", opr_n_bytes_p1, reg, opr_decode},
   1085     [0x65] = {"adc", opr_n_bytes_p1, reg, opr_decode},
   1086     [0x66] = {"adc", opr_n_bytes_p1, reg, opr_decode},
   1087     [0x67] = {"adc", opr_n_bytes_p1, reg, opr_decode},
   1088     [0x68] = {"bit", opr_n_bytes_p1, reg, opr_decode},
   1089     [0x69] = {"bit", opr_n_bytes_p1, reg, opr_decode},
   1090     [0x6a] = {"bit", opr_n_bytes_p1, reg, opr_decode},
   1091     [0x6b] = {"bit", opr_n_bytes_p1, reg, opr_decode},
   1092     [0x6c] = {"bit", opr_n_bytes_p1, reg, opr_decode},
   1093     [0x6d] = {"bit", opr_n_bytes_p1, reg, opr_decode},
   1094     [0x6e] = {"bit", opr_n_bytes_p1, reg, opr_decode},
   1095     [0x6f] = {"bit", opr_n_bytes_p1, reg, opr_decode},
   1096     [0x70] = {"sbc", three, reg, imm1234_0base},
   1097     [0x71] = {"sbc", three, reg, imm1234_0base},
   1098     [0x72] = {"sbc", three, reg, imm1234_0base},
   1099     [0x73] = {"sbc", three, reg, imm1234_0base},
   1100     [0x74] = {"sbc", two,   reg, imm1234_0base},
   1101     [0x75] = {"sbc", two,   reg, imm1234_0base},
   1102     [0x76] = {"sbc", five,  reg, imm1234_0base},
   1103     [0x77] = {"sbc", five,  reg, imm1234_0base},
   1104     [0x78] = {"eor", three, reg, imm1234_8base},
   1105     [0x79] = {"eor", three, reg, imm1234_8base},
   1106     [0x7a] = {"eor", three, reg, imm1234_8base},
   1107     [0x7b] = {"eor", three, reg, imm1234_8base},
   1108     [0x7c] = {"eor", two,   reg, imm1234_8base},
   1109     [0x7d] = {"eor", two,   reg, imm1234_8base},
   1110     [0x7e] = {"eor", five,  reg, imm1234_8base},
   1111     [0x7f] = {"eor", five,  reg, imm1234_8base},
   1112     [0x80] = {"sbc", opr_n_bytes_p1, reg, opr_decode},
   1113     [0x81] = {"sbc", opr_n_bytes_p1, reg, opr_decode},
   1114     [0x82] = {"sbc", opr_n_bytes_p1, reg, opr_decode},
   1115     [0x83] = {"sbc", opr_n_bytes_p1, reg, opr_decode},
   1116     [0x84] = {"sbc", opr_n_bytes_p1, reg, opr_decode},
   1117     [0x85] = {"sbc", opr_n_bytes_p1, reg, opr_decode},
   1118     [0x86] = {"sbc", opr_n_bytes_p1, reg, opr_decode},
   1119     [0x87] = {"sbc", opr_n_bytes_p1, reg, opr_decode},
   1120     [0x88] = {"eor", opr_n_bytes_p1, reg,    opr_decode},
   1121     [0x89] = {"eor", opr_n_bytes_p1, reg,    opr_decode},
   1122     [0x8a] = {"eor", opr_n_bytes_p1, reg,    opr_decode},
   1123     [0x8b] = {"eor", opr_n_bytes_p1, reg,    opr_decode},
   1124     [0x8c] = {"eor", opr_n_bytes_p1, reg,    opr_decode},
   1125     [0x8d] = {"eor", opr_n_bytes_p1, reg,    opr_decode},
   1126     [0x8e] = {"eor", opr_n_bytes_p1, reg,    opr_decode},
   1127     [0x8f] = {"eor", opr_n_bytes_p1, reg,    opr_decode},
   1128     [0x90] = {"rti",  single, 0, 0},
   1129     [0x91] = {"clb",   two, tfr, 0},
   1130     [0x92] = {"trap",  single, trap_decode, 0},
   1131     [0x93] = {"trap",  single, trap_decode, 0},
   1132     [0x94] = {"trap",  single, trap_decode, 0},
   1133     [0x95] = {"trap",  single, trap_decode, 0},
   1134     [0x96] = {"trap",  single, trap_decode, 0},
   1135     [0x97] = {"trap",  single, trap_decode, 0},
   1136     [0x98] = {"trap",  single, trap_decode, 0},
   1137     [0x99] = {"trap",  single, trap_decode, 0},
   1138     [0x9a] = {"trap",  single, trap_decode, 0},
   1139     [0x9b] = {"trap",  single, trap_decode, 0},
   1140     [0x9c] = {"trap",  single, trap_decode, 0},
   1141     [0x9d] = {"trap",  single, trap_decode, 0},
   1142     [0x9e] = {"trap",  single, trap_decode, 0},
   1143     [0x9f] = {"trap",  single, trap_decode, 0},
   1144     [0xa0] = {"sat", single, reg, 0},
   1145     [0xa1] = {"sat", single, reg, 0},
   1146     [0xa2] = {"sat", single, reg, 0},
   1147     [0xa3] = {"sat", single, reg, 0},
   1148     [0xa4] = {"sat", single, reg, 0},
   1149     [0xa5] = {"sat", single, reg, 0},
   1150     [0xa6] = {"sat", single, reg, 0},
   1151     [0xa7] = {"sat", single, reg, 0},
   1152     [0xa8] = {"trap",  single, trap_decode, 0},
   1153     [0xa9] = {"trap",  single, trap_decode, 0},
   1154     [0xaa] = {"trap",  single, trap_decode, 0},
   1155     [0xab] = {"trap",  single, trap_decode, 0},
   1156     [0xac] = {"trap",  single, trap_decode, 0},
   1157     [0xad] = {"trap",  single, trap_decode, 0},
   1158     [0xae] = {"trap",  single, trap_decode, 0},
   1159     [0xaf] = {"trap",  single, trap_decode, 0},
   1160     [0xb0] = {"qmul", mul_n_bytes, mul_decode, 0},
   1161     [0xb1] = {"qmul", mul_n_bytes, mul_decode, 0},
   1162     [0xb2] = {"qmul", mul_n_bytes, mul_decode, 0},
   1163     [0xb3] = {"qmul", mul_n_bytes, mul_decode, 0},
   1164     [0xb4] = {"qmul", mul_n_bytes, mul_decode, 0},
   1165     [0xb5] = {"qmul", mul_n_bytes, mul_decode, 0},
   1166     [0xb6] = {"qmul", mul_n_bytes, mul_decode, 0},
   1167     [0xb7] = {"qmul", mul_n_bytes, mul_decode, 0},
   1168     [0xb8] = {"trap",  single, trap_decode, 0},
   1169     [0xb9] = {"trap",  single, trap_decode, 0},
   1170     [0xba] = {"trap",  single, trap_decode, 0},
   1171     [0xbb] = {"trap",  single, trap_decode, 0},
   1172     [0xbc] = {"trap",  single, trap_decode, 0},
   1173     [0xbd] = {"trap",  single, trap_decode, 0},
   1174     [0xbe] = {"trap",  single, trap_decode, 0},
   1175     [0xbf] = {"trap",  single, trap_decode, 0},
   1176     [0xc0] = {"trap",  single, trap_decode, 0},
   1177     [0xc1] = {"trap",  single, trap_decode, 0},
   1178     [0xc2] = {"trap",  single, trap_decode, 0},
   1179     [0xc3] = {"trap",  single, trap_decode, 0},
   1180     [0xc4] = {"trap",  single, trap_decode, 0},
   1181     [0xc5] = {"trap",  single, trap_decode, 0},
   1182     [0xc6] = {"trap",  single, trap_decode, 0},
   1183     [0xc7] = {"trap",  single, trap_decode, 0},
   1184     [0xc8] = {"trap",  single, trap_decode, 0},
   1185     [0xc9] = {"trap",  single, trap_decode, 0},
   1186     [0xca] = {"trap",  single, trap_decode, 0},
   1187     [0xcb] = {"trap",  single, trap_decode, 0},
   1188     [0xcc] = {"trap",  single, trap_decode, 0},
   1189     [0xcd] = {"trap",  single, trap_decode, 0},
   1190     [0xce] = {"trap",  single, trap_decode, 0},
   1191     [0xcf] = {"trap",  single, trap_decode, 0},
   1192     [0xd0] = {"trap",  single, trap_decode, 0},
   1193     [0xd1] = {"trap",  single, trap_decode, 0},
   1194     [0xd2] = {"trap",  single, trap_decode, 0},
   1195     [0xd3] = {"trap",  single, trap_decode, 0},
   1196     [0xd4] = {"trap",  single, trap_decode, 0},
   1197     [0xd5] = {"trap",  single, trap_decode, 0},
   1198     [0xd6] = {"trap",  single, trap_decode, 0},
   1199     [0xd7] = {"trap",  single, trap_decode, 0},
   1200     [0xd8] = {"trap",  single, trap_decode, 0},
   1201     [0xd9] = {"trap",  single, trap_decode, 0},
   1202     [0xda] = {"trap",  single, trap_decode, 0},
   1203     [0xdb] = {"trap",  single, trap_decode, 0},
   1204     [0xdc] = {"trap",  single, trap_decode, 0},
   1205     [0xdd] = {"trap",  single, trap_decode, 0},
   1206     [0xde] = {"trap",  single, trap_decode, 0},
   1207     [0xdf] = {"trap",  single, trap_decode, 0},
   1208     [0xe0] = {"trap",  single, trap_decode, 0},
   1209     [0xe1] = {"trap",  single, trap_decode, 0},
   1210     [0xe2] = {"trap",  single, trap_decode, 0},
   1211     [0xe3] = {"trap",  single, trap_decode, 0},
   1212     [0xe4] = {"trap",  single, trap_decode, 0},
   1213     [0xe5] = {"trap",  single, trap_decode, 0},
   1214     [0xe6] = {"trap",  single, trap_decode, 0},
   1215     [0xe7] = {"trap",  single, trap_decode, 0},
   1216     [0xe8] = {"trap",  single, trap_decode, 0},
   1217     [0xe9] = {"trap",  single, trap_decode, 0},
   1218     [0xea] = {"trap",  single, trap_decode, 0},
   1219     [0xeb] = {"trap",  single, trap_decode, 0},
   1220     [0xec] = {"trap",  single, trap_decode, 0},
   1221     [0xed] = {"trap",  single, trap_decode, 0},
   1222     [0xee] = {"trap",  single, trap_decode, 0},
   1223     [0xef] = {"trap",  single, trap_decode, 0},
   1224     [0xf0] = {"trap",  single, trap_decode, 0},
   1225     [0xf1] = {"trap",  single, trap_decode, 0},
   1226     [0xf2] = {"trap",  single, trap_decode, 0},
   1227     [0xf3] = {"trap",  single, trap_decode, 0},
   1228     [0xf4] = {"trap",  single, trap_decode, 0},
   1229     [0xf5] = {"trap",  single, trap_decode, 0},
   1230     [0xf6] = {"trap",  single, trap_decode, 0},
   1231     [0xf7] = {"trap",  single, trap_decode, 0},
   1232     [0xf8] = {"trap",  single, trap_decode, 0},
   1233     [0xf9] = {"trap",  single, trap_decode, 0},
   1234     [0xfa] = {"trap",  single, trap_decode, 0},
   1235     [0xfb] = {"trap",  single, trap_decode, 0},
   1236     [0xfc] = {"trap",  single, trap_decode, 0},
   1237     [0xfd] = {"trap",  single, trap_decode, 0},
   1238     [0xfe] = {"trap",  single, trap_decode, 0},
   1239     [0xff] = {"trap",  single, trap_decode, 0},
   1240   };
   1241 
   1242 static const struct opcode page1[] =
   1243   {
   1244     [0x00] = {"bgnd", single, 0, 0},
   1245     [0x01] = {"nop",  single, 0, 0},
   1246     [0x02] = {"brclr", bm_rel_n_bytes, bm_rel_decode, 0},
   1247     [0x03] = {"brset", bm_rel_n_bytes, bm_rel_decode, 0},
   1248     [0x04] = {NULL,   two,    0, 0}, /* psh/pul */
   1249     [0x05] = {"rts",  single, 0, 0},
   1250     [0x06] = {"lea", opr_n_bytes_p1, reg, opr_decode},
   1251     [0x07] = {"lea", opr_n_bytes_p1, reg, opr_decode},
   1252     [0x08] = {"lea", opr_n_bytes_p1, lea_reg_xys_opr, 0},
   1253     [0x09] = {"lea", opr_n_bytes_p1, lea_reg_xys_opr, 0},
   1254     [0x0a] = {"lea", opr_n_bytes_p1, lea_reg_xys_opr, 0},
   1255     [0x0b] = {NULL, loop_prim_n_bytes, 0, 0}, /* Loop primitives TBcc / DBcc */
   1256     [0x0c] = {"mov.b", mov_imm_opr_n_bytes, mov_imm_opr, 0},
   1257     [0x0d] = {"mov.w", mov_imm_opr_n_bytes, mov_imm_opr, 0},
   1258     [0x0e] = {"mov.p", mov_imm_opr_n_bytes, mov_imm_opr, 0},
   1259     [0x0f] = {"mov.l", mov_imm_opr_n_bytes, mov_imm_opr, 0},
   1260     [0x10] = {NULL,   shift_n_bytes, 0, 0},  /* lsr/lsl/asl/asr/rol/ror */
   1261     [0x11] = {NULL,   shift_n_bytes, 0, 0},
   1262     [0x12] = {NULL,   shift_n_bytes, 0, 0},
   1263     [0x13] = {NULL,   shift_n_bytes, 0, 0},
   1264     [0x14] = {NULL,   shift_n_bytes, 0, 0},
   1265     [0x15] = {NULL,   shift_n_bytes, 0, 0},
   1266     [0x16] = {NULL,   shift_n_bytes, 0, 0},
   1267     [0x17] = {NULL,   shift_n_bytes, 0, 0},
   1268     [0x18] = {"lea",  two, lea_reg_xys, NULL},
   1269     [0x19] = {"lea",  two, lea_reg_xys, NULL},
   1270     [0x1a] = {"lea",  two, lea_reg_xys, NULL},
   1271     /* 0x1b PG2 */
   1272     [0x1c] = {"mov.b", opr_n_bytes2, 0, opr_decode2},
   1273     [0x1d] = {"mov.w", opr_n_bytes2, 0, opr_decode2},
   1274     [0x1e] = {"mov.p", opr_n_bytes2, 0, opr_decode2},
   1275     [0x1f] = {"mov.l", opr_n_bytes2, 0, opr_decode2},
   1276     [0x20] = {"bra",  pcrel_15bit, decode_rel_15_7, 0},
   1277     [0x21] = {"bsr",  pcrel_15bit, decode_rel_15_7, 0},
   1278     [0x22] = {"bhi",  pcrel_15bit, decode_rel_15_7, 0},
   1279     [0x23] = {"bls",  pcrel_15bit, decode_rel_15_7, 0},
   1280     [0x24] = {"bcc",  pcrel_15bit, decode_rel_15_7, 0},
   1281     [0x25] = {"bcs",  pcrel_15bit, decode_rel_15_7, 0},
   1282     [0x26] = {"bne",  pcrel_15bit, decode_rel_15_7, 0},
   1283     [0x27] = {"beq",  pcrel_15bit, decode_rel_15_7, 0},
   1284     [0x28] = {"bvc",  pcrel_15bit, decode_rel_15_7, 0},
   1285     [0x29] = {"bvs",  pcrel_15bit, decode_rel_15_7, 0},
   1286     [0x2a] = {"bpl",  pcrel_15bit, decode_rel_15_7, 0},
   1287     [0x2b] = {"bmi",  pcrel_15bit, decode_rel_15_7, 0},
   1288     [0x2c] = {"bge",  pcrel_15bit, decode_rel_15_7, 0},
   1289     [0x2d] = {"blt",  pcrel_15bit, decode_rel_15_7, 0},
   1290     [0x2e] = {"bgt",  pcrel_15bit, decode_rel_15_7, 0},
   1291     [0x2f] = {"ble",  pcrel_15bit, decode_rel_15_7, 0},
   1292     [0x30] = {"inc", single, reg, 0},
   1293     [0x31] = {"inc", single, reg, 0},
   1294     [0x32] = {"inc", single, reg, 0},
   1295     [0x33] = {"inc", single, reg, 0},
   1296     [0x34] = {"inc", single, reg, 0},
   1297     [0x35] = {"inc", single, reg, 0},
   1298     [0x36] = {"inc", single, reg, 0},
   1299     [0x37] = {"inc", single, reg, 0},
   1300     [0x38] = {"clr", single, reg, 0},
   1301     [0x39] = {"clr", single, reg, 0},
   1302     [0x3a] = {"clr", single, reg, 0},
   1303     [0x3b] = {"clr", single, reg, 0},
   1304     [0x3c] = {"clr", single, reg, 0},
   1305     [0x3d] = {"clr", single, reg, 0},
   1306     [0x3e] = {"clr", single, reg, 0},
   1307     [0x3f] = {"clr", single, reg, 0},
   1308     [0x40] = {"dec", single, reg, 0},
   1309     [0x41] = {"dec", single, reg, 0},
   1310     [0x42] = {"dec", single, reg, 0},
   1311     [0x43] = {"dec", single, reg, 0},
   1312     [0x44] = {"dec", single, reg, 0},
   1313     [0x45] = {"dec", single, reg, 0},
   1314     [0x46] = {"dec", single, reg, 0},
   1315     [0x47] = {"dec", single, reg, 0},
   1316     [0x48] = {"mul", mul_n_bytes, mul_decode, 0},
   1317     [0x49] = {"mul", mul_n_bytes, mul_decode, 0},
   1318     [0x4a] = {"mul", mul_n_bytes, mul_decode, 0},
   1319     [0x4b] = {"mul", mul_n_bytes, mul_decode, 0},
   1320     [0x4c] = {"mul", mul_n_bytes, mul_decode, 0},
   1321     [0x4d] = {"mul", mul_n_bytes, mul_decode, 0},
   1322     [0x4e] = {"mul", mul_n_bytes, mul_decode, 0},
   1323     [0x4f] = {"mul", mul_n_bytes, mul_decode, 0},
   1324     [0x50] = {"add", three, reg, imm1234_0base},
   1325     [0x51] = {"add", three, reg, imm1234_0base},
   1326     [0x52] = {"add", three, reg, imm1234_0base},
   1327     [0x53] = {"add", three, reg, imm1234_0base},
   1328     [0x54] = {"add", two,   reg, imm1234_0base},
   1329     [0x55] = {"add", two,   reg, imm1234_0base},
   1330     [0x56] = {"add", five,  reg, imm1234_0base},
   1331     [0x57] = {"add", five,  reg, imm1234_0base},
   1332     [0x58] = {"and", three, reg, imm1234_8base},
   1333     [0x59] = {"and", three, reg, imm1234_8base},
   1334     [0x5a] = {"and", three, reg, imm1234_8base},
   1335     [0x5b] = {"and", three, reg, imm1234_8base},
   1336     [0x5c] = {"and", two,   reg, imm1234_8base},
   1337     [0x5d] = {"and", two,   reg, imm1234_8base},
   1338     [0x5e] = {"and", five,  reg, imm1234_8base},
   1339     [0x5f] = {"and", five,  reg, imm1234_8base},
   1340     [0x60] = {"add", opr_n_bytes_p1, reg, opr_decode},
   1341     [0x61] = {"add", opr_n_bytes_p1, reg, opr_decode},
   1342     [0x62] = {"add", opr_n_bytes_p1, reg, opr_decode},
   1343     [0x63] = {"add", opr_n_bytes_p1, reg, opr_decode},
   1344     [0x64] = {"add", opr_n_bytes_p1, reg, opr_decode},
   1345     [0x65] = {"add", opr_n_bytes_p1, reg, opr_decode},
   1346     [0x66] = {"add", opr_n_bytes_p1, reg, opr_decode},
   1347     [0x67] = {"add", opr_n_bytes_p1, reg, opr_decode},
   1348     [0x68] = {"and", opr_n_bytes_p1, reg, opr_decode},
   1349     [0x69] = {"and", opr_n_bytes_p1, reg, opr_decode},
   1350     [0x6a] = {"and", opr_n_bytes_p1, reg, opr_decode},
   1351     [0x6b] = {"and", opr_n_bytes_p1, reg, opr_decode},
   1352     [0x6c] = {"and", opr_n_bytes_p1, reg, opr_decode},
   1353     [0x6d] = {"and", opr_n_bytes_p1, reg, opr_decode},
   1354     [0x6e] = {"and", opr_n_bytes_p1, reg, opr_decode},
   1355     [0x6f] = {"and", opr_n_bytes_p1, reg, opr_decode},
   1356     [0x70] = {"sub", three, reg, imm1234_0base},
   1357     [0x71] = {"sub", three, reg, imm1234_0base},
   1358     [0x72] = {"sub", three, reg, imm1234_0base},
   1359     [0x73] = {"sub", three, reg, imm1234_0base},
   1360     [0x74] = {"sub", two,   reg, imm1234_0base},
   1361     [0x75] = {"sub", two,   reg, imm1234_0base},
   1362     [0x76] = {"sub", five,  reg, imm1234_0base},
   1363     [0x77] = {"sub", five,  reg, imm1234_0base},
   1364     [0x78] = {"or", three, reg, imm1234_8base},
   1365     [0x79] = {"or", three, reg, imm1234_8base},
   1366     [0x7a] = {"or", three, reg, imm1234_8base},
   1367     [0x7b] = {"or", three, reg, imm1234_8base},
   1368     [0x7c] = {"or", two,   reg, imm1234_8base},
   1369     [0x7d] = {"or", two,   reg, imm1234_8base},
   1370     [0x7e] = {"or", five,  reg, imm1234_8base},
   1371     [0x7f] = {"or", five,  reg, imm1234_8base},
   1372     [0x80] = {"sub", opr_n_bytes_p1, reg,    opr_decode},
   1373     [0x81] = {"sub", opr_n_bytes_p1, reg,    opr_decode},
   1374     [0x82] = {"sub", opr_n_bytes_p1, reg,    opr_decode},
   1375     [0x83] = {"sub", opr_n_bytes_p1, reg,    opr_decode},
   1376     [0x84] = {"sub", opr_n_bytes_p1, reg,    opr_decode},
   1377     [0x85] = {"sub", opr_n_bytes_p1, reg,    opr_decode},
   1378     [0x86] = {"sub", opr_n_bytes_p1, reg,    opr_decode},
   1379     [0x87] = {"sub", opr_n_bytes_p1, reg,    opr_decode},
   1380     [0x88] = {"or", opr_n_bytes_p1, reg,    opr_decode},
   1381     [0x89] = {"or", opr_n_bytes_p1, reg,    opr_decode},
   1382     [0x8a] = {"or", opr_n_bytes_p1, reg,    opr_decode},
   1383     [0x8b] = {"or", opr_n_bytes_p1, reg,    opr_decode},
   1384     [0x8c] = {"or", opr_n_bytes_p1, reg,    opr_decode},
   1385     [0x8d] = {"or", opr_n_bytes_p1, reg,    opr_decode},
   1386     [0x8e] = {"or", opr_n_bytes_p1, reg,    opr_decode},
   1387     [0x8f] = {"or", opr_n_bytes_p1, reg,    opr_decode},
   1388     [0x90] = {"ld", three,  reg, imm1234_0base},
   1389     [0x91] = {"ld", three,  reg, imm1234_0base},
   1390     [0x92] = {"ld", three,  reg, imm1234_0base},
   1391     [0x93] = {"ld", three,  reg, imm1234_0base},
   1392     [0x94] = {"ld", two,    reg, imm1234_0base},
   1393     [0x95] = {"ld", two,    reg, imm1234_0base},
   1394     [0x96] = {"ld", five,   reg, imm1234_0base},
   1395     [0x97] = {"ld", five,   reg, imm1234_0base},
   1396     [0x98] = {"ld", four,   reg_xy, imm1234_0base},
   1397     [0x99] = {"ld", four,   reg_xy, imm1234_0base},
   1398     [0x9a] = {"clr", single, reg_xy, 0},
   1399     [0x9b] = {"clr", single, reg_xy, 0},
   1400     [0x9c] = {"inc.b", opr_n_bytes_p1, 0, opr_decode},
   1401     [0x9d] = {"inc.w", opr_n_bytes_p1, 0, opr_decode},
   1402     [0x9e] = {"tfr", two, tfr, NULL},
   1403     [0x9f] = {"inc.l", opr_n_bytes_p1, 0, opr_decode},
   1404     [0xa0] = {"ld", opr_n_bytes_p1, reg,    opr_decode},
   1405     [0xa1] = {"ld", opr_n_bytes_p1, reg,    opr_decode},
   1406     [0xa2] = {"ld", opr_n_bytes_p1, reg,    opr_decode},
   1407     [0xa3] = {"ld", opr_n_bytes_p1, reg,    opr_decode},
   1408     [0xa4] = {"ld", opr_n_bytes_p1, reg,    opr_decode},
   1409     [0xa5] = {"ld", opr_n_bytes_p1, reg,    opr_decode},
   1410     [0xa6] = {"ld", opr_n_bytes_p1, reg,    opr_decode},
   1411     [0xa7] = {"ld", opr_n_bytes_p1, reg,    opr_decode},
   1412     [0xa8] = {"ld", opr_n_bytes_p1, reg_xy, opr_decode},
   1413     [0xa9] = {"ld", opr_n_bytes_p1, reg_xy, opr_decode},
   1414     [0xaa] = {"jmp", opr_n_bytes_p1, opr_decode, 0},
   1415     [0xab] = {"jsr", opr_n_bytes_p1, opr_decode, 0},
   1416     [0xac] = {"dec.b", opr_n_bytes_p1, 0, opr_decode},
   1417     [0xad] = {"dec.w", opr_n_bytes_p1, 0, opr_decode},
   1418     [0xae] = {NULL,   two, 0, 0},  /* EXG / SEX */
   1419     [0xaf] = {"dec.l", opr_n_bytes_p1, 0, opr_decode},
   1420     [0xb0] = {"ld", four,  reg, ext24_decode},
   1421     [0xb1] = {"ld", four,  reg, ext24_decode},
   1422     [0xb2] = {"ld", four,  reg, ext24_decode},
   1423     [0xb3] = {"ld", four,  reg, ext24_decode},
   1424     [0xb4] = {"ld", four,  reg, ext24_decode},
   1425     [0xb5] = {"ld", four,  reg, ext24_decode},
   1426     [0xb6] = {"ld", four,  reg, ext24_decode},
   1427     [0xb7] = {"ld", four,  reg, ext24_decode},
   1428     [0xb8] = {"ld", four,  reg_xy, ext24_decode},
   1429     [0xb9] = {"ld", four,  reg_xy, ext24_decode},
   1430     [0xba] = {"jmp", four, ext24_decode, 0},
   1431     [0xbb] = {"jsr", four, ext24_decode, 0},
   1432     [0xbc] = {"clr.b", opr_n_bytes_p1, 0, opr_decode},
   1433     [0xbd] = {"clr.w", opr_n_bytes_p1, 0, opr_decode},
   1434     [0xbe] = {"clr.p", opr_n_bytes_p1, 0, opr_decode},
   1435     [0xbf] = {"clr.l", opr_n_bytes_p1, 0, opr_decode},
   1436     [0xc0] = {"st", opr_n_bytes_p1, reg,    opr_decode},
   1437     [0xc1] = {"st", opr_n_bytes_p1, reg,    opr_decode},
   1438     [0xc2] = {"st", opr_n_bytes_p1, reg,    opr_decode},
   1439     [0xc3] = {"st", opr_n_bytes_p1, reg,    opr_decode},
   1440     [0xc4] = {"st", opr_n_bytes_p1, reg,    opr_decode},
   1441     [0xc5] = {"st", opr_n_bytes_p1, reg,    opr_decode},
   1442     [0xc6] = {"st", opr_n_bytes_p1, reg,    opr_decode},
   1443     [0xc7] = {"st", opr_n_bytes_p1, reg,    opr_decode},
   1444     [0xc8] = {"st", opr_n_bytes_p1, reg_xy, opr_decode},
   1445     [0xc9] = {"st", opr_n_bytes_p1, reg_xy, opr_decode},
   1446     [0xca] = {"ld", three, reg_xy, ld_18bit_decode},
   1447     [0xcb] = {"ld", three, reg_xy, ld_18bit_decode},
   1448     [0xcc] = {"com.b", opr_n_bytes_p1, NULL, opr_decode},
   1449     [0xcd] = {"com.w", opr_n_bytes_p1, NULL, opr_decode},
   1450     [0xce] = {"andcc", two, imm1, 0},
   1451     [0xcf] = {"com.l", opr_n_bytes_p1, NULL, opr_decode},
   1452     [0xd0] = {"st", four,  reg, ext24_decode},
   1453     [0xd1] = {"st", four,  reg, ext24_decode},
   1454     [0xd2] = {"st", four,  reg, ext24_decode},
   1455     [0xd3] = {"st", four,  reg, ext24_decode},
   1456     [0xd4] = {"st", four,  reg, ext24_decode},
   1457     [0xd5] = {"st", four,  reg, ext24_decode},
   1458     [0xd6] = {"st", four,  reg, ext24_decode},
   1459     [0xd7] = {"st", four,  reg, ext24_decode},
   1460     [0xd8] = {"st", four,  reg_xy, ext24_decode},
   1461     [0xd9] = {"st", four,  reg_xy, ext24_decode},
   1462     [0xda] = {"ld", three, reg_xy, ld_18bit_decode},
   1463     [0xdb] = {"ld", three, reg_xy, ld_18bit_decode},
   1464     [0xdc] = {"neg.b", opr_n_bytes_p1, NULL, opr_decode},
   1465     [0xdd] = {"neg.w", opr_n_bytes_p1, NULL, opr_decode},
   1466     [0xde] = {"orcc",  two,  imm1, 0},
   1467     [0xdf] = {"neg.l", opr_n_bytes_p1, NULL, opr_decode},
   1468     [0xe0] = {"cmp", three,  reg, imm1234_0base},
   1469     [0xe1] = {"cmp", three,  reg, imm1234_0base},
   1470     [0xe2] = {"cmp", three,  reg, imm1234_0base},
   1471     [0xe3] = {"cmp", three,  reg, imm1234_0base},
   1472     [0xe4] = {"cmp", two,    reg, imm1234_0base},
   1473     [0xe5] = {"cmp", two,    reg, imm1234_0base},
   1474     [0xe6] = {"cmp", five,   reg, imm1234_0base},
   1475     [0xe7] = {"cmp", five,   reg, imm1234_0base},
   1476     [0xe8] = {"cmp", four,   reg_xy, imm1234_0base},
   1477     [0xe9] = {"cmp", four,   reg_xy, imm1234_0base},
   1478     [0xea] = {"ld", three, reg_xy, ld_18bit_decode},
   1479     [0xeb] = {"ld", three, reg_xy, ld_18bit_decode},
   1480     [0xec] = {"bclr", bm_n_bytes, bm_decode, 0},
   1481     [0xed] = {"bset", bm_n_bytes, bm_decode, 0},
   1482     [0xee] = {"btgl", bm_n_bytes, bm_decode, 0},
   1483     [0xef] = {"!!invalid!!", NULL, NULL, NULL}, /* SPARE */
   1484     [0xf0] = {"cmp", opr_n_bytes_p1, reg,    opr_decode},
   1485     [0xf1] = {"cmp", opr_n_bytes_p1, reg,    opr_decode},
   1486     [0xf2] = {"cmp", opr_n_bytes_p1, reg,    opr_decode},
   1487     [0xf3] = {"cmp", opr_n_bytes_p1, reg,    opr_decode},
   1488     [0xf4] = {"cmp", opr_n_bytes_p1, reg,    opr_decode},
   1489     [0xf5] = {"cmp", opr_n_bytes_p1, reg,    opr_decode},
   1490     [0xf6] = {"cmp", opr_n_bytes_p1, reg,    opr_decode},
   1491     [0xf7] = {"cmp", opr_n_bytes_p1, reg,    opr_decode},
   1492     [0xf8] = {"cmp", opr_n_bytes_p1, reg_xy, opr_decode},
   1493     [0xf9] = {"cmp", opr_n_bytes_p1, reg_xy, opr_decode},
   1494     [0xfa] = {"ld",  three, reg_xy, ld_18bit_decode},
   1495     [0xfb] = {"ld",  three, reg_xy, ld_18bit_decode},
   1496     [0xfc] = {"cmp", single, cmp_xy, 0},
   1497     [0xfd] = {"sub", single, sub_d6_x_y, 0},
   1498     [0xfe] = {"sub", single, sub_d6_y_x, 0},
   1499     [0xff] = {"swi", single, 0, 0}
   1500   };
   1501 
   1502 
   1503 static const char *oprregs1[] =
   1504   {
   1505     "d3", "d2", "d1", "d0", "ccl", "cch"
   1506   };
   1507 
   1508 static const char *oprregs2[] =
   1509   {
   1510     "y", "x", "d7", "d6", "d5", "d4"
   1511   };
   1512 
   1513 
   1514 
   1515 
   1517 enum MUL_MODE
   1518   {
   1519     MUL_REG_REG,
   1520     MUL_REG_OPR,
   1521     MUL_REG_IMM,
   1522     MUL_OPR_OPR
   1523   };
   1524 
   1525 struct mb
   1526 {
   1527   uint8_t mask;
   1528   uint8_t value;
   1529   enum MUL_MODE mode;
   1530 };
   1531 
   1532 static const struct mb mul_table[] = {
   1533   {0x40, 0x00, MUL_REG_REG},
   1534 
   1535   {0x47, 0x40, MUL_REG_OPR},
   1536   {0x47, 0x41, MUL_REG_OPR},
   1537   {0x47, 0x43, MUL_REG_OPR},
   1538 
   1539   {0x47, 0x44, MUL_REG_IMM},
   1540   {0x47, 0x45, MUL_REG_IMM},
   1541   {0x47, 0x47, MUL_REG_IMM},
   1542 
   1543   {0x43, 0x42, MUL_OPR_OPR},
   1544 };
   1545 
   1546 static void
   1547 mul_decode (bfd_vma memaddr, struct disassemble_info* info)
   1548 {
   1549   uint8_t mb;
   1550   int status = read_memory (memaddr, &mb, 1, info);
   1551   if (status < 0)
   1552     return;
   1553 
   1554 
   1555   uint8_t byte;
   1556   status = read_memory (memaddr - 1, &byte, 1, info);
   1557   if (status < 0)
   1558     return;
   1559 
   1560   (*info->fprintf_func) (info->stream, "%c", (mb & 0x80) ? 's' : 'u');
   1561 
   1562   enum MUL_MODE mode = -1;
   1563   size_t i;
   1564   for (i = 0; i < sizeof (mul_table) / sizeof (mul_table[0]); ++i)
   1565     {
   1566       const struct mb *mm = mul_table + i;
   1567       if ((mb & mm->mask) == mm->value)
   1568 	{
   1569 	  mode = mm->mode;
   1570 	  break;
   1571 	}
   1572     }
   1573 
   1574   switch (mode)
   1575     {
   1576     case MUL_REG_REG:
   1577       break;
   1578     case MUL_OPR_OPR:
   1579       {
   1580 	int size1 = (mb & 0x30) >> 4;
   1581 	int size2 = (mb & 0x0c) >> 2;
   1582 	(*info->fprintf_func) (info->stream, ".%c%c",
   1583 			       shift_size_table [size1],
   1584 			       shift_size_table [size2]);
   1585       }
   1586       break;
   1587     default:
   1588       {
   1589 	int size = (mb & 0x3);
   1590 	(*info->fprintf_func) (info->stream, ".%c", shift_size_table [size]);
   1591       }
   1592       break;
   1593     }
   1594 
   1595   operand_separator (info);
   1596   (*info->fprintf_func) (info->stream, "%s", registers[byte & 0x7].name);
   1597 
   1598   switch (mode)
   1599     {
   1600     case MUL_REG_REG:
   1601     case MUL_REG_IMM:
   1602     case MUL_REG_OPR:
   1603       operand_separator (info);
   1604       (*info->fprintf_func) (info->stream, "%s", registers[(mb & 0x38) >> 3].name);
   1605       break;
   1606     default:
   1607       break;
   1608     }
   1609 
   1610   switch (mode)
   1611     {
   1612     case MUL_REG_IMM:
   1613       operand_separator (info);
   1614       int size = (mb & 0x3);
   1615       uint32_t imm = decode_signed_value (memaddr + 1, info, size + 1);
   1616       (*info->fprintf_func) (info->stream, "#%d", imm);
   1617       break;
   1618     case MUL_REG_REG:
   1619       operand_separator (info);
   1620       (*info->fprintf_func) (info->stream, "%s", registers[mb & 0x07].name);
   1621       break;
   1622     case MUL_REG_OPR:
   1623       opr_decode (memaddr + 1, info);
   1624       break;
   1625     case MUL_OPR_OPR:
   1626       {
   1627 	int first = opr_n_bytes (memaddr + 1, info);
   1628 	opr_decode (memaddr + 1, info);
   1629 	opr_decode (memaddr + first + 1, info);
   1630 	break;
   1631       }
   1632     }
   1633 }
   1634 
   1635 
   1636 static int
   1637 mul_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
   1638 {
   1639   int nx = 2;
   1640   uint8_t mb;
   1641   int status = read_memory (memaddr, &mb, 1, info);
   1642   if (status < 0)
   1643     return 0;
   1644 
   1645   enum MUL_MODE mode = -1;
   1646   size_t i;
   1647   for (i = 0; i < sizeof (mul_table) / sizeof (mul_table[0]); ++i)
   1648     {
   1649       const struct mb *mm = mul_table + i;
   1650       if ((mb & mm->mask) == mm->value)
   1651 	{
   1652 	  mode = mm->mode;
   1653 	  break;
   1654 	}
   1655     }
   1656 
   1657   int size = (mb & 0x3) + 1;
   1658 
   1659   switch (mode)
   1660     {
   1661     case MUL_REG_IMM:
   1662       nx += size;
   1663       break;
   1664     case MUL_REG_REG:
   1665       break;
   1666     case MUL_REG_OPR:
   1667       nx += opr_n_bytes (memaddr + 1, info);
   1668       break;
   1669     case MUL_OPR_OPR:
   1670       {
   1671 	int first = opr_n_bytes (memaddr + nx - 1, info);
   1672 	nx += first;
   1673 	int second = opr_n_bytes (memaddr + nx - 1, info);
   1674 	nx += second;
   1675       }
   1676       break;
   1677     }
   1678 
   1679   return nx;
   1680 }
   1681 
   1682 
   1683 enum BM_MODE {
   1685   BM_REG_IMM,
   1686   BM_RESERVED0,
   1687   BM_OPR_B,
   1688   BM_OPR_W,
   1689   BM_OPR_L,
   1690   BM_OPR_REG,
   1691   BM_RESERVED1
   1692 };
   1693 
   1694 struct bm
   1695 {
   1696   uint8_t mask;
   1697   uint8_t value;
   1698   enum BM_MODE mode;
   1699 };
   1700 
   1701 static const  struct bm bm_table[] = {
   1702   { 0xC6, 0x04,     BM_REG_IMM},
   1703   { 0x84, 0x00,     BM_REG_IMM},
   1704   { 0x06, 0x06,     BM_REG_IMM},
   1705   { 0xC6, 0x44,     BM_RESERVED0},
   1706   // 00
   1707   { 0x8F, 0x80,     BM_OPR_B},
   1708   { 0x8E, 0x82,     BM_OPR_W},
   1709   { 0x8C, 0x88,     BM_OPR_L},
   1710 
   1711   { 0x83, 0x81,     BM_OPR_REG},
   1712   { 0x87, 0x84,     BM_RESERVED1},
   1713 };
   1714 
   1715 static void
   1716 bm_decode (bfd_vma memaddr, struct disassemble_info* info)
   1717 {
   1718   uint8_t bm;
   1719   int status = read_memory (memaddr, &bm, 1, info);
   1720   if (status < 0)
   1721     return;
   1722 
   1723   size_t i;
   1724   enum BM_MODE mode = -1;
   1725   for (i = 0; i < sizeof (bm_table) / sizeof (bm_table[0]); ++i)
   1726     {
   1727       const struct bm *bme = bm_table + i;
   1728       if ((bm & bme->mask) == bme->value)
   1729 	{
   1730 	  mode = bme->mode;
   1731 	  break;
   1732 	}
   1733     }
   1734 
   1735   switch (mode)
   1736     {
   1737     case BM_REG_IMM:
   1738       operand_separator (info);
   1739       (*info->fprintf_func) (info->stream, "%s", registers[bm & 0x07].name);
   1740       break;
   1741     case BM_OPR_B:
   1742       (*info->fprintf_func) (info->stream, ".%c", 'b');
   1743       opr_decode (memaddr + 1, info);
   1744       break;
   1745     case BM_OPR_W:
   1746       (*info->fprintf_func) (info->stream, ".%c", 'w');
   1747       opr_decode (memaddr + 1, info);
   1748       break;
   1749     case BM_OPR_L:
   1750       (*info->fprintf_func) (info->stream, ".%c", 'l');
   1751       opr_decode (memaddr + 1, info);
   1752       break;
   1753     case BM_OPR_REG:
   1754       {
   1755 	uint8_t xb;
   1756 	read_memory (memaddr + 1, &xb, 1, info);
   1757 	/* Don't emit a size suffix for register operands */
   1758 	if ((xb & 0xF8) != 0xB8)
   1759 	  (*info->fprintf_func) (info->stream, ".%c", shift_size_table[(bm & 0x0c) >> 2]);
   1760 	opr_decode (memaddr + 1, info);
   1761       }
   1762       break;
   1763     case BM_RESERVED0:
   1764     case BM_RESERVED1:
   1765       assert (0);
   1766       break;
   1767     }
   1768 
   1769   uint8_t imm = 0;
   1770   operand_separator (info);
   1771   switch (mode)
   1772     {
   1773     case BM_REG_IMM:
   1774       {
   1775 	imm = (bm & 0xF8) >> 3;
   1776 	(*info->fprintf_func) (info->stream, "#%d", imm);
   1777       }
   1778       break;
   1779     case BM_OPR_L:
   1780       imm |= (bm & 0x03) << 3;
   1781       /* fallthrough */
   1782     case BM_OPR_W:
   1783       imm |= (bm & 0x01) << 3;
   1784       /* fallthrough */
   1785     case BM_OPR_B:
   1786       imm |= (bm & 0x70) >> 4;
   1787       (*info->fprintf_func) (info->stream, "#%d", imm);
   1788       break;
   1789     case BM_OPR_REG:
   1790       (*info->fprintf_func) (info->stream, "%s", registers[(bm & 0x70) >> 4].name);
   1791       break;
   1792     case BM_RESERVED0:
   1793     case BM_RESERVED1:
   1794       assert (0);
   1795       break;
   1796     }
   1797 }
   1798 
   1799 
   1800 static void
   1801 bm_rel_decode (bfd_vma memaddr, struct disassemble_info* info)
   1802 {
   1803   uint8_t bm;
   1804   int status = read_memory (memaddr, &bm, 1, info);
   1805   if (status < 0)
   1806     return;
   1807 
   1808   size_t i;
   1809   enum BM_MODE mode = -1;
   1810   for (i = 0; i < sizeof (bm_table) / sizeof (bm_table[0]); ++i)
   1811     {
   1812       const struct bm *bme = bm_table + i;
   1813       if ((bm & bme->mask) == bme->value)
   1814 	{
   1815 	  mode = bme->mode;
   1816 	  break;
   1817 	}
   1818     }
   1819 
   1820   switch (mode)
   1821     {
   1822     case BM_REG_IMM:
   1823       break;
   1824     case BM_OPR_B:
   1825       (*info->fprintf_func) (info->stream, ".%c", 'b');
   1826       break;
   1827     case BM_OPR_W:
   1828       (*info->fprintf_func) (info->stream, ".%c", 'w');
   1829       break;
   1830     case BM_OPR_L:
   1831       (*info->fprintf_func) (info->stream, ".%c", 'l');
   1832       break;
   1833     case BM_OPR_REG:
   1834       {
   1835 	uint8_t xb;
   1836 	read_memory (memaddr + 1, &xb, 1, info);
   1837 	/* Don't emit a size suffix for register operands */
   1838 	if ((xb & 0xF8) != 0xB8)
   1839 	  (*info->fprintf_func) (info->stream, ".%c",
   1840 				 shift_size_table[(bm & 0x0C) >> 2]);
   1841       }
   1842       break;
   1843     case BM_RESERVED0:
   1844     case BM_RESERVED1:
   1845       assert (0);
   1846       break;
   1847     }
   1848 
   1849   int n = 1;
   1850   switch (mode)
   1851     {
   1852     case BM_REG_IMM:
   1853       operand_separator (info);
   1854       (*info->fprintf_func) (info->stream, "%s", registers[bm & 0x07].name);
   1855       break;
   1856     case BM_OPR_B:
   1857     case BM_OPR_W:
   1858     case BM_OPR_L:
   1859       opr_decode (memaddr + 1, info);
   1860       n = 1 + opr_n_bytes (memaddr + 1, info);
   1861       break;
   1862     case BM_OPR_REG:
   1863       opr_decode (memaddr + 1, info);
   1864       break;
   1865     case BM_RESERVED0:
   1866     case BM_RESERVED1:
   1867       assert (0);
   1868       break;
   1869     }
   1870 
   1871 
   1872   int imm = 0;
   1873   operand_separator (info);
   1874   switch (mode)
   1875     {
   1876     case BM_OPR_L:
   1877       imm |= (bm & 0x02) << 3;
   1878       /* fall through */
   1879     case BM_OPR_W:
   1880       imm |= (bm & 0x01) << 3;
   1881       /* fall through */
   1882     case BM_OPR_B:
   1883       imm |= (bm & 0x70) >> 4;
   1884       (*info->fprintf_func) (info->stream, "#%d", imm);
   1885       break;
   1886     case BM_REG_IMM:
   1887       imm = (bm & 0xF8) >> 3;
   1888       (*info->fprintf_func) (info->stream, "#%d", imm);
   1889       break;
   1890     case BM_RESERVED0:
   1891     case BM_RESERVED1:
   1892       assert (0);
   1893       break;
   1894     case BM_OPR_REG:
   1895       (*info->fprintf_func) (info->stream, "%s", registers[(bm & 0x70) >> 4].name);
   1896       n += opr_n_bytes (memaddr + 1, info);
   1897       break;
   1898     }
   1899 
   1900   rel_15_7 (memaddr + n, info, n + 1);
   1901 }
   1902 
   1903 static int
   1904 bm_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
   1905 {
   1906   uint8_t bm;
   1907   int status = read_memory (memaddr, &bm, 1, info);
   1908   if (status < 0)
   1909     return status;
   1910 
   1911   size_t i;
   1912   enum BM_MODE mode = -1;
   1913   for (i = 0; i < sizeof (bm_table) / sizeof (bm_table[0]); ++i)
   1914     {
   1915       const struct bm *bme = bm_table + i;
   1916       if ((bm & bme->mask) == bme->value)
   1917 	{
   1918 	  mode = bme->mode;
   1919 	  break;
   1920 	}
   1921     }
   1922 
   1923   int n = 2;
   1924   switch (mode)
   1925     {
   1926     case BM_REG_IMM:
   1927       break;
   1928 
   1929     case BM_OPR_B:
   1930     case BM_OPR_W:
   1931     case BM_OPR_L:
   1932       n += opr_n_bytes (memaddr + 1, info);
   1933       break;
   1934     case BM_OPR_REG:
   1935       n += opr_n_bytes (memaddr + 1, info);
   1936       break;
   1937     default:
   1938       break;
   1939   }
   1940 
   1941   return n;
   1942 }
   1943 
   1944 static int
   1945 bm_rel_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
   1946 {
   1947   int n = 1 + bm_n_bytes (memaddr, info);
   1948 
   1949   bfd_byte rb;
   1950   int status = read_memory (memaddr + n - 2, &rb, 1, info);
   1951   if (status != 0)
   1952     return status;
   1953 
   1954   if (rb & 0x80)
   1955     n++;
   1956 
   1957   return n;
   1958 }
   1959 
   1960 
   1961 
   1962 
   1964 
   1965 /* shift direction */
   1966 enum SB_DIR
   1967   {
   1968     SB_LEFT,
   1969     SB_RIGHT
   1970   };
   1971 
   1972 enum SB_TYPE
   1973   {
   1974     SB_ARITHMETIC,
   1975     SB_LOGICAL
   1976   };
   1977 
   1978 
   1979 enum SB_MODE
   1980   {
   1981     SB_REG_REG_N_EFF,
   1982     SB_REG_REG_N,
   1983     SB_REG_OPR_EFF,
   1984     SB_ROT,
   1985     SB_REG_OPR_OPR,
   1986     SB_OPR_N
   1987   };
   1988 
   1989 struct sb
   1990 {
   1991   uint8_t mask;
   1992   uint8_t value;
   1993   enum SB_MODE mode;
   1994 };
   1995 
   1996 static const  struct sb sb_table[] = {
   1997   {0x30, 0x00,     SB_REG_REG_N_EFF},
   1998   {0x30, 0x10,     SB_REG_REG_N},
   1999   {0x34, 0x20,     SB_REG_OPR_EFF},
   2000   {0x34, 0x24,     SB_ROT},
   2001   {0x34, 0x30,     SB_REG_OPR_OPR},
   2002   {0x34, 0x34,     SB_OPR_N},
   2003 };
   2004 
   2005 static int
   2006 shift_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
   2007 {
   2008   bfd_byte sb;
   2009   int status = read_memory (memaddr++, &sb, 1, info);
   2010   if (status != 0)
   2011     return status;
   2012 
   2013   size_t i;
   2014   enum SB_MODE mode = -1;
   2015   for (i = 0; i < sizeof (sb_table) / sizeof (sb_table[0]); ++i)
   2016     {
   2017       const struct sb *sbe = sb_table + i;
   2018       if ((sb & sbe->mask) == sbe->value)
   2019 	mode = sbe->mode;
   2020     }
   2021 
   2022   switch (mode)
   2023     {
   2024     case SB_REG_REG_N_EFF:
   2025       return 2;
   2026       break;
   2027     case SB_REG_OPR_EFF:
   2028     case SB_ROT:
   2029 	return 2 + opr_n_bytes (memaddr, info);
   2030       break;
   2031     case SB_REG_OPR_OPR:
   2032       {
   2033 	int opr1 = opr_n_bytes (memaddr, info);
   2034 	int opr2 = 0;
   2035 	if ((sb & 0x30) != 0x20)
   2036 	  opr2 = opr_n_bytes (memaddr + opr1, info);
   2037 	return 2 + opr1 + opr2;
   2038       }
   2039       break;
   2040     default:
   2041       return 3;
   2042     }
   2043 
   2044   /* not reached */
   2045   return -1;
   2046 }
   2047 
   2048 
   2050 static int
   2051 mov_imm_opr_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
   2052 {
   2053   bfd_byte byte;
   2054   int status = read_memory (memaddr - 1, &byte, 1, info);
   2055   if (status < 0)
   2056     return status;
   2057 
   2058   int size = byte - 0x0c + 1;
   2059 
   2060   return size + opr_n_bytes (memaddr + size, info) + 1;
   2061 }
   2062 
   2063 static void
   2064 mov_imm_opr (bfd_vma memaddr, struct disassemble_info* info)
   2065 {
   2066   bfd_byte byte;
   2067   int status = read_memory (memaddr - 1, &byte, 1, info);
   2068   if (status < 0)
   2069     return ;
   2070 
   2071   int size = byte - 0x0c + 1;
   2072   uint32_t imm = decode_signed_value (memaddr, info, size);
   2073 
   2074   operand_separator (info);
   2075   (*info->fprintf_func) (info->stream, "#%d", imm);
   2076   opr_decode (memaddr + size, info);
   2077 }
   2078 
   2079 
   2080 
   2082 static void
   2083 ld_18bit_decode (bfd_vma memaddr, struct disassemble_info* info)
   2084 {
   2085   size_t size = 3;
   2086   bfd_byte buffer[3];
   2087   int status = read_memory (memaddr, buffer + 1, 2, info);
   2088   if (status < 0)
   2089     return ;
   2090 
   2091 
   2092   status = read_memory (memaddr - 1, buffer, 1, info);
   2093   if (status < 0)
   2094     return ;
   2095 
   2096   buffer[0] = (buffer[0] & 0x30) >> 4;
   2097 
   2098   size_t i;
   2099   uint32_t imm = 0;
   2100   for (i = 0; i < size; ++i)
   2101     {
   2102       imm |= buffer[i] << (8 * (size - i - 1));
   2103     }
   2104 
   2105   operand_separator (info);
   2106   (*info->fprintf_func) (info->stream, "#%d", imm);
   2107 }
   2108 
   2109 
   2110 
   2112 /* Loop Primitives */
   2113 
   2114 enum LP_MODE {
   2115   LP_REG,
   2116   LP_XY,
   2117   LP_OPR
   2118 };
   2119 
   2120 struct lp
   2121 {
   2122   uint8_t mask;
   2123   uint8_t value;
   2124   enum LP_MODE mode;
   2125 };
   2126 
   2127 static const struct lp lp_mode[] = {
   2128   {0x08, 0x00, LP_REG},
   2129   {0x0C, 0x08, LP_XY},
   2130   {0x0C, 0x0C, LP_OPR},
   2131 };
   2132 
   2133 
   2134 static const char *lb_condition[] =
   2135   {
   2136     "ne", "eq", "pl", "mi", "gt", "le",
   2137     "??", "??"
   2138   };
   2139 
   2140 static int
   2141 loop_prim_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
   2142 {
   2143   int mx = 0;
   2144   uint8_t lb;
   2145   read_memory (memaddr + mx++, &lb, 1, info);
   2146 
   2147   enum LP_MODE mode = -1;
   2148   size_t i;
   2149   for (i = 0; i < sizeof (lp_mode) / sizeof (lp_mode[0]); ++i)
   2150     {
   2151       const struct lp *pb = lp_mode + i;
   2152       if ((lb & pb->mask) == pb->value)
   2153 	{
   2154 	  mode = pb->mode;
   2155 	  break;
   2156 	}
   2157     }
   2158 
   2159   if (mode == LP_OPR)
   2160     {
   2161       mx += opr_n_bytes (memaddr + mx, info) ;
   2162     }
   2163 
   2164   uint8_t rb;
   2165   read_memory (memaddr + mx++, &rb, 1, info);
   2166   if (rb & 0x80)
   2167     mx++;
   2168 
   2169   return mx + 1;
   2170 }
   2171 
   2172 
   2173 
   2174 
   2176 static int
   2177 print_insn_exg_sex (bfd_vma memaddr, struct disassemble_info* info)
   2178 {
   2179   uint8_t eb;
   2180   int status = read_memory (memaddr, &eb, 1, info);
   2181   if (status < 0)
   2182     return -1;
   2183 
   2184   const struct reg *first =  &registers[(eb & 0xf0) >> 4];
   2185   const struct reg *second = &registers[(eb & 0xf)];
   2186 
   2187   if (first->bytes < second->bytes)
   2188     (*info->fprintf_func) (info->stream, "sex");
   2189   else
   2190     (*info->fprintf_func) (info->stream, "exg");
   2191 
   2192   operand_separator (info);
   2193   (*info->fprintf_func) (info->stream, "%s", first->name);
   2194   operand_separator (info);
   2195   (*info->fprintf_func) (info->stream, "%s", second->name);
   2196   return 0;
   2197 }
   2198 
   2199 
   2200 
   2201 static int
   2202 print_insn_loop_primitive (bfd_vma memaddr, struct disassemble_info* info)
   2203 {
   2204   int offs = 1;
   2205   uint8_t lb;
   2206   int status = read_memory (memaddr, &lb, 1, info);
   2207 
   2208   char mnemonic[7];
   2209   int x = 0;
   2210   mnemonic[x++] = (lb & 0x80) ? 'd' : 't';
   2211   mnemonic[x++] = 'b';
   2212   stpcpy (mnemonic + x, lb_condition [(lb & 0x70) >> 4]);
   2213   x += 2;
   2214 
   2215   const char *reg  = NULL;
   2216   enum LP_MODE mode = -1;
   2217   size_t i;
   2218   for (i = 0; i < sizeof (lp_mode) / sizeof (lp_mode[0]); ++i)
   2219     {
   2220       const struct lp *pb = lp_mode + i;
   2221       if ((lb & pb->mask) == pb->value)
   2222 	{
   2223 	  mode = pb->mode;
   2224 	  break;
   2225 	}
   2226     }
   2227 
   2228   switch (mode)
   2229     {
   2230     case LP_REG:
   2231       reg = registers [lb & 0x07].name;
   2232       break;
   2233     case LP_XY:
   2234       reg = (lb & 0x1) ? "y" : "x";
   2235       break;
   2236     case LP_OPR:
   2237       mnemonic[x++] = '.';
   2238       mnemonic[x++] = shift_size_table [lb & 0x03];
   2239       offs += opr_n_bytes (memaddr + 1, info);
   2240       break;
   2241     }
   2242 
   2243   mnemonic[x++] = '\0';
   2244 
   2245   (*info->fprintf_func) (info->stream, "%s", mnemonic);
   2246 
   2247   if (mode == LP_OPR)
   2248     opr_decode (memaddr + 1, info);
   2249   else
   2250     {
   2251       operand_separator (info);
   2252       (*info->fprintf_func) (info->stream, "%s", reg);
   2253     }
   2254 
   2255   rel_15_7 (memaddr + offs, info, offs + 1);
   2256 
   2257   return status;
   2258 }
   2259 
   2260 
   2261 static int
   2262 print_insn_shift (bfd_vma memaddr, struct disassemble_info* info, uint8_t byte)
   2263 {
   2264   size_t i;
   2265   uint8_t sb;
   2266   int status = read_memory (memaddr, &sb, 1, info);
   2267   if (status < 0)
   2268     return status;
   2269 
   2270   enum SB_DIR  dir = (sb & 0x40) ? SB_LEFT : SB_RIGHT;
   2271   enum SB_TYPE type = (sb & 0x80) ? SB_ARITHMETIC : SB_LOGICAL;
   2272   enum SB_MODE mode = -1;
   2273   for (i = 0; i < sizeof (sb_table) / sizeof (sb_table[0]); ++i)
   2274     {
   2275       const struct sb *sbe = sb_table + i;
   2276       if ((sb & sbe->mask) == sbe->value)
   2277 	mode = sbe->mode;
   2278     }
   2279 
   2280   char mnemonic[6];
   2281   int x = 0;
   2282   if (mode == SB_ROT)
   2283     {
   2284       mnemonic[x++] = 'r';
   2285       mnemonic[x++] = 'o';
   2286     }
   2287   else
   2288     {
   2289       mnemonic[x++] = (type == SB_LOGICAL) ? 'l' : 'a';
   2290       mnemonic[x++] = 's';
   2291     }
   2292 
   2293   mnemonic[x++] = (dir == SB_LEFT) ? 'l' : 'r';
   2294 
   2295   switch (mode)
   2296     {
   2297     case SB_REG_OPR_EFF:
   2298     case SB_ROT:
   2299     case SB_REG_OPR_OPR:
   2300       mnemonic[x++] = '.';
   2301       mnemonic[x++] = shift_size_table[sb & 0x03];
   2302       break;
   2303     case SB_OPR_N:
   2304       {
   2305 	uint8_t xb;
   2306 	read_memory (memaddr + 1, &xb, 1, info);
   2307 	/* The size suffix is not printed if the OPR operand refers
   2308 	   directly to a register, because the size is implied by the
   2309 	   size of that register. */
   2310 	if ((xb & 0xF8) != 0xB8)
   2311 	  {
   2312 	    mnemonic[x++] = '.';
   2313 	    mnemonic[x++] = shift_size_table[sb & 0x03];
   2314 	  }
   2315       }
   2316       break;
   2317     default:
   2318       break;
   2319     };
   2320 
   2321   mnemonic[x++] = '\0';
   2322 
   2323   (*info->fprintf_func) (info->stream, "%s", mnemonic);
   2324 
   2325   /* Destination register */
   2326   switch (mode)
   2327     {
   2328     case SB_REG_REG_N_EFF:
   2329     case SB_REG_REG_N:
   2330     case SB_REG_OPR_EFF:
   2331     case SB_REG_OPR_OPR:
   2332       operand_separator (info);
   2333       (*info->fprintf_func) (info->stream, "%s", registers[byte & 0x7].name);
   2334       break;
   2335 
   2336     case SB_ROT:
   2337       opr_decode (memaddr + 1, info);
   2338       break;
   2339 
   2340     default:
   2341       break;
   2342     }
   2343 
   2344   /* Source register */
   2345   switch (mode)
   2346     {
   2347     case SB_REG_REG_N_EFF:
   2348     case SB_REG_REG_N:
   2349       operand_separator (info);
   2350       (*info->fprintf_func) (info->stream, "%s", registers[sb & 0x7].name);
   2351       break;
   2352 
   2353     case SB_REG_OPR_OPR:
   2354       opr_decode (memaddr + 1, info);
   2355       break;
   2356 
   2357     default:
   2358       break;
   2359     }
   2360 
   2361   /* 3rd arg */
   2362   switch (mode)
   2363     {
   2364     case SB_REG_OPR_EFF:
   2365     case SB_OPR_N:
   2366       opr_decode (memaddr + 1, info);
   2367       break;
   2368 
   2369     case SB_REG_REG_N:
   2370       if (sb & 0x08)
   2371 	{
   2372 	  operand_separator (info);
   2373 	  if (byte & 0x10)
   2374 	    {
   2375 	      uint8_t xb;
   2376 	      read_memory (memaddr + 1, &xb, 1, info);
   2377 	      int shift = ((sb & 0x08) >> 3) | ((xb & 0x0f) << 1);
   2378 	      (*info->fprintf_func) (info->stream, "#%d", shift);
   2379 	    }
   2380 	  else
   2381 	    {
   2382 	      (*info->fprintf_func) (info->stream, "%s:%d", __FILE__, __LINE__);
   2383 	    }
   2384 	}
   2385       else
   2386 	{
   2387 	  opr_decode (memaddr + 1, info);
   2388 	}
   2389       break;
   2390     case SB_REG_OPR_OPR:
   2391       {
   2392       uint8_t xb;
   2393       int n = opr_n_bytes (memaddr + 1, info);
   2394       read_memory (memaddr + 1 + n, &xb, 1, info);
   2395 
   2396       if ((xb & 0xF0) == 0x70)
   2397 	{
   2398 	  int imm = xb & 0x0F;
   2399 	  imm <<= 1;
   2400 	  imm |= (sb & 0x08) >> 3;
   2401 	  operand_separator (info);
   2402 	  (*info->fprintf_func) (info->stream, "#%d", imm);
   2403 	}
   2404       else
   2405 	{
   2406 	  opr_decode (memaddr + 1 + n, info);
   2407 	}
   2408       }
   2409       break;
   2410     default:
   2411       break;
   2412     }
   2413 
   2414   switch (mode)
   2415     {
   2416     case SB_REG_REG_N_EFF:
   2417     case SB_REG_OPR_EFF:
   2418     case SB_OPR_N:
   2419       operand_separator (info);
   2420       (*info->fprintf_func) (info->stream, "#%d",
   2421 			     (sb & 0x08) ? 2 : 1);
   2422       break;
   2423 
   2424     default:
   2425       break;
   2426     }
   2427 
   2428   return 0;
   2429 }
   2430 
   2431 int
   2432 print_insn_s12z (bfd_vma memaddr, struct disassemble_info* info)
   2433 {
   2434   bfd_byte byte;
   2435   int status = read_memory (memaddr++, &byte, 1, info);
   2436   if (status != 0)
   2437     return status;
   2438 
   2439   const struct opcode *opc2 = NULL;
   2440   const struct opcode *opc = page1 + byte;
   2441   if (opc->mnemonic)
   2442     {
   2443       (*info->fprintf_func) (info->stream, "%s", opc->mnemonic);
   2444     }
   2445   else
   2446     {
   2447       /* The special cases ... */
   2448       switch (byte)
   2449 	{
   2450 	case PAGE2_PREBYTE:
   2451 	  {
   2452 	    bfd_byte byte2;
   2453 	    read_memory (memaddr++, &byte2, 1, info);
   2454 	    opc2 = page2 + byte2;
   2455 	    if (opc2->mnemonic)
   2456 	      {
   2457 		(*info->fprintf_func) (info->stream, "%s", opc2->mnemonic);
   2458 
   2459 		if (opc2->operands)
   2460 		  {
   2461 		    opc2->operands (memaddr, info);
   2462 		  }
   2463 
   2464 		if (opc2->operands2)
   2465 		  {
   2466 		    opc2->operands2 (memaddr, info);
   2467 		  }
   2468 	      }
   2469 	    else if (byte2 >= 0x08 && byte2 <= 0x1F)
   2470 	      {
   2471 		bfd_byte bb;
   2472 		read_memory (memaddr, &bb, 1, info);
   2473 		if (bb & 0x80)
   2474 		  (*info->fprintf_func) (info->stream, "bfins");
   2475 		else
   2476 		  (*info->fprintf_func) (info->stream, "bfext");
   2477 
   2478 		enum BB_MODE mode = -1;
   2479 		size_t i;
   2480 		const struct opr_bb *bbs = 0;
   2481 		for (i = 0; i < sizeof (bb_modes) / sizeof (bb_modes[0]); ++i)
   2482 		  {
   2483 		    bbs = bb_modes + i;
   2484 		    if ((bb & bbs->mask) == bbs->value)
   2485 		      {
   2486 			mode = bbs->mode;
   2487 			break;
   2488 		      }
   2489 		  }
   2490 
   2491 		switch (mode)
   2492 		  {
   2493 		  case BB_REG_OPR_REG:
   2494 		  case BB_REG_OPR_IMM:
   2495 		  case BB_OPR_REG_REG:
   2496 		  case BB_OPR_REG_IMM:
   2497 		    {
   2498 		      int size = (bb >> 2) & 0x03;
   2499 		      (*info->fprintf_func) (info->stream, ".%c",
   2500 					     shift_size_table [size]);
   2501 		    }
   2502 		    break;
   2503 		  default:
   2504 		    break;
   2505 		  }
   2506 
   2507 		int reg1 = byte2 & 0x07;
   2508 		/* First operand */
   2509 		switch (mode)
   2510 		  {
   2511 		  case BB_REG_REG_REG:
   2512 		  case BB_REG_REG_IMM:
   2513 		  case BB_REG_OPR_REG:
   2514 		  case BB_REG_OPR_IMM:
   2515 		    operand_separator (info);
   2516 		    (*info->fprintf_func) (info->stream, "%s",
   2517 					   registers[reg1].name);
   2518 		    break;
   2519 		  case BB_OPR_REG_REG:
   2520 		    opr_decode (memaddr + 1, info);
   2521 		    break;
   2522 		  case BB_OPR_REG_IMM:
   2523 		    opr_decode (memaddr + 2, info);
   2524 		    break;
   2525 		  }
   2526 
   2527 		/* Second operand */
   2528 		switch (mode)
   2529 		  {
   2530 		  case BB_REG_REG_REG:
   2531 		  case BB_REG_REG_IMM:
   2532 		    {
   2533 		      int reg_src = (bb >> 2) & 0x07;
   2534 		      operand_separator (info);
   2535 		      (*info->fprintf_func) (info->stream, "%s",
   2536 					     registers[reg_src].name);
   2537 		    }
   2538 		    break;
   2539 		  case BB_OPR_REG_REG:
   2540 		  case BB_OPR_REG_IMM:
   2541 		    {
   2542 		      int reg_src = (byte2 & 0x07);
   2543 		      operand_separator (info);
   2544 		      (*info->fprintf_func) (info->stream, "%s",
   2545 					     registers[reg_src].name);
   2546 		    }
   2547 		    break;
   2548 		  case BB_REG_OPR_REG:
   2549 		    opr_decode (memaddr + 1, info);
   2550 		    break;
   2551 		  case BB_REG_OPR_IMM:
   2552 		    opr_decode (memaddr + 2, info);
   2553 		    break;
   2554 		  }
   2555 
   2556 		/* Third operand */
   2557 		operand_separator (info);
   2558 		switch (mode)
   2559 		  {
   2560 		  case BB_REG_REG_REG:
   2561 		  case BB_OPR_REG_REG:
   2562 		  case BB_REG_OPR_REG:
   2563 		    {
   2564 		      int reg_parm = bb & 0x03;
   2565 		      (*info->fprintf_func) (info->stream, "%s",
   2566 					     registers[reg_parm].name);
   2567 		    }
   2568 		    break;
   2569 		  case BB_REG_REG_IMM:
   2570 		  case BB_OPR_REG_IMM:
   2571 		  case BB_REG_OPR_IMM:
   2572 		    {
   2573 		      bfd_byte i1;
   2574 		      read_memory (memaddr + 1, &i1, 1, info);
   2575 		      int offset = i1 & 0x1f;
   2576 		      int width = bb & 0x03;
   2577 		      width <<= 3;
   2578 		      width |= i1 >> 5;
   2579 		      (*info->fprintf_func) (info->stream, "#%d:%d", width,  offset);
   2580 		    }
   2581 		    break;
   2582 		  }
   2583 	      }
   2584 	  }
   2585 	  break;
   2586 	case 0xae: /* EXG / SEX */
   2587 	  status = print_insn_exg_sex (memaddr, info);
   2588 	  break;
   2589 	case 0x0b:  /* Loop Primitives TBcc and DBcc */
   2590 	  status = print_insn_loop_primitive (memaddr, info);
   2591 	  break;
   2592 	case 0x10:  	    /* shift */
   2593 	case 0x11:  	    /* shift */
   2594 	case 0x12:  	    /* shift */
   2595 	case 0x13:  	    /* shift */
   2596 	case 0x14:  	    /* shift */
   2597 	case 0x15:  	    /* shift */
   2598 	case 0x16:  	    /* shift */
   2599 	case 0x17:  	    /* shift */
   2600 	  status = print_insn_shift (memaddr, info, byte);
   2601 	  break;
   2602 	case 0x04:  	    /* psh / pul */
   2603 	  {
   2604 	    read_memory (memaddr, &byte, 1, info);
   2605 	    (*info->fprintf_func) (info->stream, (byte & 0x80) ? "pul" : "psh");
   2606 	    int bit;
   2607 	    if (byte & 0x40)
   2608 	      {
   2609 		if ((byte & 0x3F) == 0)
   2610 		  {
   2611 		    operand_separator (info);
   2612 		    (*info->fprintf_func) (info->stream, "%s", "ALL16b");
   2613 		  }
   2614 		else
   2615 		  for (bit = 5; bit >= 0; --bit)
   2616 		    {
   2617 		      if (byte & (0x1 << bit))
   2618 			{
   2619 			  operand_separator (info);
   2620 			  (*info->fprintf_func) (info->stream, "%s", oprregs2[bit]);
   2621 			}
   2622 		    }
   2623 	      }
   2624 	    else
   2625 	      {
   2626 		if ((byte & 0x3F) == 0)
   2627 		  {
   2628 		    operand_separator (info);
   2629 		    (*info->fprintf_func) (info->stream, "%s", "ALL");
   2630 		  }
   2631 		else
   2632 		  for (bit = 5; bit >= 0; --bit)
   2633 		    {
   2634 		      if (byte & (0x1 << bit))
   2635 			{
   2636 			  operand_separator (info);
   2637 			  (*info->fprintf_func) (info->stream, "%s", oprregs1[bit]);
   2638 			}
   2639 		    }
   2640 	      }
   2641 	  }
   2642 	  break;
   2643 	default:
   2644 	  operand_separator (info);
   2645 	  (*info->fprintf_func) (info->stream, "???");
   2646 	  break;
   2647 	}
   2648     }
   2649 
   2650   if (opc2 == NULL)
   2651     {
   2652       if (opc->operands)
   2653 	{
   2654 	  opc->operands (memaddr, info);
   2655 	}
   2656 
   2657       if (opc->operands2)
   2658 	{
   2659 	  opc->operands2 (memaddr, info);
   2660 	}
   2661     }
   2662 
   2663   int n = 0;
   2664 
   2665   /* Opcodes in page2 have an additional byte */
   2666   if (opc2)
   2667     n++;
   2668 
   2669   if (opc2 && opc2->insn_bytes == 0)
   2670     return n;
   2671 
   2672   if (!opc2 && opc->insn_bytes == 0)
   2673     return n;
   2674 
   2675   if (opc2)
   2676     n += opc2->insn_bytes (memaddr, info);
   2677   else
   2678     n += opc->insn_bytes (memaddr, info);
   2679 
   2680   return n;
   2681 }
   2682