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