Home | History | Annotate | Line # | Download | only in opcodes
m68k-dis.c revision 1.7
      1  1.1  christos /* Print Motorola 68k instructions.
      2  1.7  christos    Copyright (C) 1986-2017 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 "dis-asm.h"
     23  1.1  christos #include "floatformat.h"
     24  1.1  christos #include "libiberty.h"
     25  1.1  christos #include "opintl.h"
     26  1.1  christos 
     27  1.1  christos #include "opcode/m68k.h"
     28  1.1  christos 
     29  1.1  christos /* Local function prototypes.  */
     30  1.1  christos 
     31  1.1  christos const char * const fpcr_names[] =
     32  1.1  christos {
     33  1.1  christos   "", "%fpiar", "%fpsr", "%fpiar/%fpsr", "%fpcr",
     34  1.1  christos   "%fpiar/%fpcr", "%fpsr/%fpcr", "%fpiar/%fpsr/%fpcr"
     35  1.1  christos };
     36  1.1  christos 
     37  1.1  christos static char *const reg_names[] =
     38  1.1  christos {
     39  1.1  christos   "%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7",
     40  1.1  christos   "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%fp", "%sp",
     41  1.1  christos   "%ps", "%pc"
     42  1.1  christos };
     43  1.1  christos 
     44  1.1  christos /* Name of register halves for MAC/EMAC.
     45  1.1  christos    Seperate from reg_names since 'spu', 'fpl' look weird.  */
     46  1.1  christos static char *const reg_half_names[] =
     47  1.1  christos {
     48  1.1  christos   "%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7",
     49  1.1  christos   "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%a6", "%a7",
     50  1.1  christos   "%ps", "%pc"
     51  1.1  christos };
     52  1.1  christos 
     53  1.1  christos /* Sign-extend an (unsigned char).  */
     54  1.1  christos #if __STDC__ == 1
     55  1.1  christos #define COERCE_SIGNED_CHAR(ch) ((signed char) (ch))
     56  1.1  christos #else
     57  1.1  christos #define COERCE_SIGNED_CHAR(ch) ((int) (((ch) ^ 0x80) & 0xFF) - 128)
     58  1.1  christos #endif
     59  1.1  christos 
     60  1.7  christos /* Error code of print_insn_arg's return value.  */
     61  1.7  christos 
     62  1.7  christos enum print_insn_arg_error
     63  1.7  christos   {
     64  1.7  christos     /* An invalid operand is found.  */
     65  1.7  christos     PRINT_INSN_ARG_INVALID_OPERAND = -1,
     66  1.7  christos 
     67  1.7  christos     /* An opcode table error.  */
     68  1.7  christos     PRINT_INSN_ARG_INVALID_OP_TABLE = -2,
     69  1.7  christos 
     70  1.7  christos     /* A memory error.  */
     71  1.7  christos     PRINT_INSN_ARG_MEMORY_ERROR = -3,
     72  1.7  christos   };
     73  1.7  christos 
     74  1.1  christos /* Get a 1 byte signed integer.  */
     75  1.1  christos #define NEXTBYTE(p, val)			\
     76  1.1  christos   do						\
     77  1.1  christos     {						\
     78  1.1  christos       p += 2;					\
     79  1.1  christos       if (!FETCH_DATA (info, p))		\
     80  1.7  christos 	return PRINT_INSN_ARG_MEMORY_ERROR;	\
     81  1.1  christos       val = COERCE_SIGNED_CHAR (p[-1]);		\
     82  1.1  christos     }						\
     83  1.1  christos   while (0)
     84  1.1  christos 
     85  1.1  christos /* Get a 2 byte signed integer.  */
     86  1.1  christos #define COERCE16(x) ((int) (((x) ^ 0x8000) - 0x8000))
     87  1.1  christos 
     88  1.1  christos #define NEXTWORD(p, val, ret_val)		\
     89  1.1  christos   do						\
     90  1.1  christos     {						\
     91  1.1  christos       p += 2;					\
     92  1.1  christos       if (!FETCH_DATA (info, p))		\
     93  1.1  christos 	return ret_val;				\
     94  1.1  christos       val = COERCE16 ((p[-2] << 8) + p[-1]);	\
     95  1.1  christos     }						\
     96  1.6  christos   while (0)
     97  1.1  christos 
     98  1.1  christos /* Get a 4 byte signed integer.  */
     99  1.1  christos #define COERCE32(x) ((bfd_signed_vma) ((x) ^ 0x80000000) - 0x80000000)
    100  1.1  christos 
    101  1.1  christos #define NEXTLONG(p, val, ret_val)					\
    102  1.1  christos   do									\
    103  1.1  christos     {									\
    104  1.1  christos       p += 4;								\
    105  1.1  christos       if (!FETCH_DATA (info, p))					\
    106  1.1  christos 	return ret_val;							\
    107  1.1  christos       val = COERCE32 ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1]); \
    108  1.1  christos     }									\
    109  1.1  christos   while (0)
    110  1.1  christos 
    111  1.1  christos /* Get a 4 byte unsigned integer.  */
    112  1.1  christos #define NEXTULONG(p, val)						\
    113  1.1  christos   do									\
    114  1.1  christos     {									\
    115  1.1  christos       p += 4;								\
    116  1.1  christos       if (!FETCH_DATA (info, p))					\
    117  1.7  christos 	return PRINT_INSN_ARG_MEMORY_ERROR;				\
    118  1.1  christos       val = (unsigned int) ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1]); \
    119  1.1  christos     }									\
    120  1.1  christos   while (0)
    121  1.1  christos 
    122  1.1  christos /* Get a single precision float.  */
    123  1.1  christos #define NEXTSINGLE(val, p)					\
    124  1.1  christos   do								\
    125  1.1  christos     {								\
    126  1.1  christos       p += 4;							\
    127  1.1  christos       if (!FETCH_DATA (info, p))				\
    128  1.7  christos 	return PRINT_INSN_ARG_MEMORY_ERROR;			\
    129  1.1  christos       floatformat_to_double (& floatformat_ieee_single_big,	\
    130  1.1  christos 			     (char *) p - 4, & val);		\
    131  1.1  christos     }								\
    132  1.1  christos   while (0)
    133  1.1  christos 
    134  1.1  christos /* Get a double precision float.  */
    135  1.1  christos #define NEXTDOUBLE(val, p)					\
    136  1.1  christos   do								\
    137  1.1  christos     {								\
    138  1.1  christos       p += 8;							\
    139  1.1  christos       if (!FETCH_DATA (info, p))				\
    140  1.7  christos 	return PRINT_INSN_ARG_MEMORY_ERROR;			\
    141  1.1  christos       floatformat_to_double (& floatformat_ieee_double_big,	\
    142  1.1  christos 			     (char *) p - 8, & val);		\
    143  1.1  christos     }								\
    144  1.1  christos   while (0)
    145  1.1  christos 
    146  1.1  christos /* Get an extended precision float.  */
    147  1.1  christos #define NEXTEXTEND(val, p)				\
    148  1.1  christos   do							\
    149  1.1  christos     {							\
    150  1.1  christos       p += 12;						\
    151  1.1  christos       if (!FETCH_DATA (info, p))			\
    152  1.7  christos 	return PRINT_INSN_ARG_MEMORY_ERROR;		\
    153  1.1  christos       floatformat_to_double (& floatformat_m68881_ext,	\
    154  1.1  christos 			     (char *) p - 12, & val);	\
    155  1.1  christos     }							\
    156  1.1  christos   while (0)
    157  1.1  christos 
    158  1.1  christos /* Need a function to convert from packed to double
    159  1.1  christos    precision.   Actually, it's easier to print a
    160  1.1  christos    packed number than a double anyway, so maybe
    161  1.1  christos    there should be a special case to handle this... */
    162  1.1  christos #define NEXTPACKED(p, val)			\
    163  1.1  christos   do						\
    164  1.1  christos     {						\
    165  1.1  christos       p += 12;					\
    166  1.1  christos       if (!FETCH_DATA (info, p))		\
    167  1.7  christos 	return PRINT_INSN_ARG_MEMORY_ERROR;	\
    168  1.1  christos       val = 0.0;				\
    169  1.1  christos     }						\
    170  1.1  christos   while (0)
    171  1.1  christos 
    172  1.1  christos 
    173  1.1  christos /* Maximum length of an instruction.  */
    175  1.1  christos #define MAXLEN 22
    176  1.1  christos 
    177  1.1  christos struct private
    178  1.1  christos {
    179  1.1  christos   /* Points to first byte not fetched.  */
    180  1.1  christos   bfd_byte *max_fetched;
    181  1.1  christos   bfd_byte the_buffer[MAXLEN];
    182  1.1  christos   bfd_vma insn_start;
    183  1.1  christos };
    184  1.1  christos 
    185  1.7  christos /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
    186  1.7  christos    to ADDR (exclusive) are valid.  Returns 1 for success, 0 on memory
    187  1.1  christos    error.  */
    188  1.1  christos #define FETCH_DATA(info, addr) \
    189  1.1  christos   ((addr) <= ((struct private *) (info->private_data))->max_fetched \
    190  1.1  christos    ? 1 : fetch_data ((info), (addr)))
    191  1.1  christos 
    192  1.1  christos static int
    193  1.1  christos fetch_data (struct disassemble_info *info, bfd_byte *addr)
    194  1.1  christos {
    195  1.1  christos   int status;
    196  1.1  christos   struct private *priv = (struct private *)info->private_data;
    197  1.1  christos   bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
    198  1.1  christos 
    199  1.1  christos   status = (*info->read_memory_func) (start,
    200  1.1  christos 				      priv->max_fetched,
    201  1.1  christos 				      addr - priv->max_fetched,
    202  1.1  christos 				      info);
    203  1.1  christos   if (status != 0)
    204  1.1  christos     {
    205  1.1  christos       (*info->memory_error_func) (status, start, info);
    206  1.1  christos       return 0;
    207  1.1  christos     }
    208  1.1  christos   else
    209  1.1  christos     priv->max_fetched = addr;
    210  1.1  christos   return 1;
    211  1.1  christos }
    212  1.1  christos 
    213  1.1  christos /* This function is used to print to the bit-bucket.  */
    215  1.1  christos static int
    216  1.1  christos dummy_printer (FILE *file ATTRIBUTE_UNUSED,
    217  1.1  christos 	       const char *format ATTRIBUTE_UNUSED,
    218  1.1  christos 	       ...)
    219  1.1  christos {
    220  1.1  christos   return 0;
    221  1.1  christos }
    222  1.1  christos 
    223  1.1  christos static void
    224  1.1  christos dummy_print_address (bfd_vma vma ATTRIBUTE_UNUSED,
    225  1.1  christos 		     struct disassemble_info *info ATTRIBUTE_UNUSED)
    226  1.1  christos {
    227  1.1  christos }
    228  1.1  christos 
    229  1.1  christos /* Fetch BITS bits from a position in the instruction specified by CODE.
    230  1.1  christos    CODE is a "place to put an argument", or 'x' for a destination
    231  1.1  christos    that is a general address (mode and register).
    232  1.1  christos    BUFFER contains the instruction.
    233  1.1  christos    Returns -1 on failure.  */
    234  1.1  christos 
    235  1.1  christos static int
    236  1.1  christos fetch_arg (unsigned char *buffer,
    237  1.1  christos 	   int code,
    238  1.1  christos 	   int bits,
    239  1.1  christos 	   disassemble_info *info)
    240  1.1  christos {
    241  1.1  christos   int val = 0;
    242  1.1  christos 
    243  1.1  christos   switch (code)
    244  1.1  christos     {
    245  1.1  christos     case '/': /* MAC/EMAC mask bit.  */
    246  1.1  christos       val = buffer[3] >> 5;
    247  1.1  christos       break;
    248  1.1  christos 
    249  1.1  christos     case 'G': /* EMAC ACC load.  */
    250  1.1  christos       val = ((buffer[3] >> 3) & 0x2) | ((~buffer[1] >> 7) & 0x1);
    251  1.1  christos       break;
    252  1.1  christos 
    253  1.1  christos     case 'H': /* EMAC ACC !load.  */
    254  1.1  christos       val = ((buffer[3] >> 3) & 0x2) | ((buffer[1] >> 7) & 0x1);
    255  1.1  christos       break;
    256  1.1  christos 
    257  1.1  christos     case ']': /* EMAC ACCEXT bit.  */
    258  1.1  christos       val = buffer[0] >> 2;
    259  1.1  christos       break;
    260  1.1  christos 
    261  1.1  christos     case 'I': /* MAC/EMAC scale factor.  */
    262  1.1  christos       val = buffer[2] >> 1;
    263  1.1  christos       break;
    264  1.1  christos 
    265  1.1  christos     case 'F': /* EMAC ACCx.  */
    266  1.1  christos       val = buffer[0] >> 1;
    267  1.1  christos       break;
    268  1.1  christos 
    269  1.1  christos     case 'f':
    270  1.1  christos       val = buffer[1];
    271  1.1  christos       break;
    272  1.1  christos 
    273  1.1  christos     case 's':
    274  1.1  christos       val = buffer[1];
    275  1.1  christos       break;
    276  1.1  christos 
    277  1.1  christos     case 'd':			/* Destination, for register or quick.  */
    278  1.1  christos       val = (buffer[0] << 8) + buffer[1];
    279  1.1  christos       val >>= 9;
    280  1.1  christos       break;
    281  1.1  christos 
    282  1.1  christos     case 'x':			/* Destination, for general arg.  */
    283  1.1  christos       val = (buffer[0] << 8) + buffer[1];
    284  1.1  christos       val >>= 6;
    285  1.1  christos       break;
    286  1.1  christos 
    287  1.1  christos     case 'k':
    288  1.1  christos       if (! FETCH_DATA (info, buffer + 3))
    289  1.1  christos 	return -1;
    290  1.1  christos       val = (buffer[3] >> 4);
    291  1.1  christos       break;
    292  1.1  christos 
    293  1.1  christos     case 'C':
    294  1.1  christos       if (! FETCH_DATA (info, buffer + 3))
    295  1.1  christos 	return -1;
    296  1.1  christos       val = buffer[3];
    297  1.1  christos       break;
    298  1.1  christos 
    299  1.1  christos     case '1':
    300  1.1  christos       if (! FETCH_DATA (info, buffer + 3))
    301  1.1  christos 	return -1;
    302  1.1  christos       val = (buffer[2] << 8) + buffer[3];
    303  1.1  christos       val >>= 12;
    304  1.1  christos       break;
    305  1.1  christos 
    306  1.1  christos     case '2':
    307  1.1  christos       if (! FETCH_DATA (info, buffer + 3))
    308  1.1  christos 	return -1;
    309  1.1  christos       val = (buffer[2] << 8) + buffer[3];
    310  1.1  christos       val >>= 6;
    311  1.1  christos       break;
    312  1.1  christos 
    313  1.1  christos     case '3':
    314  1.1  christos     case 'j':
    315  1.1  christos       if (! FETCH_DATA (info, buffer + 3))
    316  1.1  christos 	return -1;
    317  1.1  christos       val = (buffer[2] << 8) + buffer[3];
    318  1.1  christos       break;
    319  1.1  christos 
    320  1.1  christos     case '4':
    321  1.1  christos       if (! FETCH_DATA (info, buffer + 5))
    322  1.1  christos 	return -1;
    323  1.1  christos       val = (buffer[4] << 8) + buffer[5];
    324  1.1  christos       val >>= 12;
    325  1.1  christos       break;
    326  1.1  christos 
    327  1.1  christos     case '5':
    328  1.1  christos       if (! FETCH_DATA (info, buffer + 5))
    329  1.1  christos 	return -1;
    330  1.1  christos       val = (buffer[4] << 8) + buffer[5];
    331  1.1  christos       val >>= 6;
    332  1.1  christos       break;
    333  1.1  christos 
    334  1.1  christos     case '6':
    335  1.1  christos       if (! FETCH_DATA (info, buffer + 5))
    336  1.1  christos 	return -1;
    337  1.1  christos       val = (buffer[4] << 8) + buffer[5];
    338  1.1  christos       break;
    339  1.1  christos 
    340  1.1  christos     case '7':
    341  1.1  christos       if (! FETCH_DATA (info, buffer + 3))
    342  1.1  christos 	return -1;
    343  1.1  christos       val = (buffer[2] << 8) + buffer[3];
    344  1.1  christos       val >>= 7;
    345  1.1  christos       break;
    346  1.1  christos 
    347  1.1  christos     case '8':
    348  1.1  christos       if (! FETCH_DATA (info, buffer + 3))
    349  1.1  christos 	return -1;
    350  1.1  christos       val = (buffer[2] << 8) + buffer[3];
    351  1.1  christos       val >>= 10;
    352  1.1  christos       break;
    353  1.1  christos 
    354  1.1  christos     case '9':
    355  1.1  christos       if (! FETCH_DATA (info, buffer + 3))
    356  1.1  christos 	return -1;
    357  1.1  christos       val = (buffer[2] << 8) + buffer[3];
    358  1.1  christos       val >>= 5;
    359  1.1  christos       break;
    360  1.1  christos 
    361  1.1  christos     case 'e':
    362  1.1  christos       val = (buffer[1] >> 6);
    363  1.1  christos       break;
    364  1.1  christos 
    365  1.1  christos     case 'E':
    366  1.1  christos       if (! FETCH_DATA (info, buffer + 3))
    367  1.1  christos 	return -1;
    368  1.1  christos       val = (buffer[2] >> 1);
    369  1.1  christos       break;
    370  1.1  christos 
    371  1.1  christos     case 'm':
    372  1.1  christos       val = (buffer[1] & 0x40 ? 0x8 : 0)
    373  1.1  christos 	| ((buffer[0] >> 1) & 0x7)
    374  1.1  christos 	| (buffer[3] & 0x80 ? 0x10 : 0);
    375  1.1  christos       break;
    376  1.1  christos 
    377  1.1  christos     case 'n':
    378  1.1  christos       val = (buffer[1] & 0x40 ? 0x8 : 0) | ((buffer[0] >> 1) & 0x7);
    379  1.1  christos       break;
    380  1.1  christos 
    381  1.1  christos     case 'o':
    382  1.1  christos       val = (buffer[2] >> 4) | (buffer[3] & 0x80 ? 0x10 : 0);
    383  1.1  christos       break;
    384  1.1  christos 
    385  1.1  christos     case 'M':
    386  1.1  christos       val = (buffer[1] & 0xf) | (buffer[3] & 0x40 ? 0x10 : 0);
    387  1.1  christos       break;
    388  1.1  christos 
    389  1.1  christos     case 'N':
    390  1.1  christos       val = (buffer[3] & 0xf) | (buffer[3] & 0x40 ? 0x10 : 0);
    391  1.1  christos       break;
    392  1.1  christos 
    393  1.1  christos     case 'h':
    394  1.1  christos       val = buffer[2] >> 2;
    395  1.1  christos       break;
    396  1.1  christos 
    397  1.1  christos     default:
    398  1.1  christos       abort ();
    399  1.1  christos     }
    400  1.1  christos 
    401  1.1  christos   /* bits is never too big.  */
    402  1.1  christos   return val & ((1 << bits) - 1);
    403  1.1  christos }
    404  1.1  christos 
    405  1.1  christos /* Check if an EA is valid for a particular code.  This is required
    406  1.1  christos    for the EMAC instructions since the type of source address determines
    407  1.1  christos    if it is a EMAC-load instruciton if the EA is mode 2-5, otherwise it
    408  1.1  christos    is a non-load EMAC instruction and the bits mean register Ry.
    409  1.1  christos    A similar case exists for the movem instructions where the register
    410  1.1  christos    mask is interpreted differently for different EAs.  */
    411  1.1  christos 
    412  1.1  christos static bfd_boolean
    413  1.1  christos m68k_valid_ea (char code, int val)
    414  1.1  christos {
    415  1.1  christos   int mode, mask;
    416  1.1  christos #define M(n0,n1,n2,n3,n4,n5,n6,n70,n71,n72,n73,n74) \
    417  1.1  christos   (n0 | n1 << 1 | n2 << 2 | n3 << 3 | n4 << 4 | n5 << 5 | n6 << 6 \
    418  1.1  christos    | n70 << 7 | n71 << 8 | n72 << 9 | n73 << 10 | n74 << 11)
    419  1.1  christos 
    420  1.1  christos   switch (code)
    421  1.1  christos     {
    422  1.1  christos     case '*':
    423  1.1  christos       mask = M (1,1,1,1,1,1,1,1,1,1,1,1);
    424  1.1  christos       break;
    425  1.1  christos     case '~':
    426  1.1  christos       mask = M (0,0,1,1,1,1,1,1,1,0,0,0);
    427  1.1  christos       break;
    428  1.1  christos     case '%':
    429  1.1  christos       mask = M (1,1,1,1,1,1,1,1,1,0,0,0);
    430  1.1  christos       break;
    431  1.1  christos     case ';':
    432  1.1  christos       mask = M (1,0,1,1,1,1,1,1,1,1,1,1);
    433  1.1  christos       break;
    434  1.1  christos     case '@':
    435  1.1  christos       mask = M (1,0,1,1,1,1,1,1,1,1,1,0);
    436  1.1  christos       break;
    437  1.1  christos     case '!':
    438  1.1  christos       mask = M (0,0,1,0,0,1,1,1,1,1,1,0);
    439  1.1  christos       break;
    440  1.1  christos     case '&':
    441  1.1  christos       mask = M (0,0,1,0,0,1,1,1,1,0,0,0);
    442  1.1  christos       break;
    443  1.1  christos     case '$':
    444  1.1  christos       mask = M (1,0,1,1,1,1,1,1,1,0,0,0);
    445  1.1  christos       break;
    446  1.1  christos     case '?':
    447  1.1  christos       mask = M (1,0,1,0,0,1,1,1,1,0,0,0);
    448  1.1  christos       break;
    449  1.1  christos     case '/':
    450  1.1  christos       mask = M (1,0,1,0,0,1,1,1,1,1,1,0);
    451  1.1  christos       break;
    452  1.1  christos     case '|':
    453  1.1  christos       mask = M (0,0,1,0,0,1,1,1,1,1,1,0);
    454  1.1  christos       break;
    455  1.1  christos     case '>':
    456  1.1  christos       mask = M (0,0,1,0,1,1,1,1,1,0,0,0);
    457  1.1  christos       break;
    458  1.1  christos     case '<':
    459  1.1  christos       mask = M (0,0,1,1,0,1,1,1,1,1,1,0);
    460  1.1  christos       break;
    461  1.1  christos     case 'm':
    462  1.1  christos       mask = M (1,1,1,1,1,0,0,0,0,0,0,0);
    463  1.1  christos       break;
    464  1.1  christos     case 'n':
    465  1.1  christos       mask = M (0,0,0,0,0,1,0,0,0,1,0,0);
    466  1.1  christos       break;
    467  1.1  christos     case 'o':
    468  1.1  christos       mask = M (0,0,0,0,0,0,1,1,1,0,1,1);
    469  1.1  christos       break;
    470  1.1  christos     case 'p':
    471  1.1  christos       mask = M (1,1,1,1,1,1,0,0,0,0,0,0);
    472  1.1  christos       break;
    473  1.1  christos     case 'q':
    474  1.1  christos       mask = M (1,0,1,1,1,1,0,0,0,0,0,0);
    475  1.1  christos       break;
    476  1.1  christos     case 'v':
    477  1.1  christos       mask = M (1,0,1,1,1,1,0,1,1,0,0,0);
    478  1.1  christos       break;
    479  1.1  christos     case 'b':
    480  1.1  christos       mask = M (1,0,1,1,1,1,0,0,0,1,0,0);
    481  1.1  christos       break;
    482  1.1  christos     case 'w':
    483  1.1  christos       mask = M (0,0,1,1,1,1,0,0,0,1,0,0);
    484  1.1  christos       break;
    485  1.1  christos     case 'y':
    486  1.1  christos       mask = M (0,0,1,0,0,1,0,0,0,0,0,0);
    487  1.1  christos       break;
    488  1.1  christos     case 'z':
    489  1.1  christos       mask = M (0,0,1,0,0,1,0,0,0,1,0,0);
    490  1.1  christos       break;
    491  1.1  christos     case '4':
    492  1.1  christos       mask = M (0,0,1,1,1,1,0,0,0,0,0,0);
    493  1.1  christos       break;
    494  1.1  christos     default:
    495  1.1  christos       abort ();
    496  1.1  christos     }
    497  1.1  christos #undef M
    498  1.1  christos 
    499  1.1  christos   mode = (val >> 3) & 7;
    500  1.1  christos   if (mode == 7)
    501  1.1  christos     mode += val & 7;
    502  1.1  christos   return (mask & (1 << mode)) != 0;
    503  1.1  christos }
    504  1.1  christos 
    505  1.1  christos /* Print a base register REGNO and displacement DISP, on INFO->STREAM.
    506  1.1  christos    REGNO = -1 for pc, -2 for none (suppressed).  */
    507  1.1  christos 
    508  1.1  christos static void
    509  1.1  christos print_base (int regno, bfd_vma disp, disassemble_info *info)
    510  1.1  christos {
    511  1.1  christos   if (regno == -1)
    512  1.1  christos     {
    513  1.1  christos       (*info->fprintf_func) (info->stream, "%%pc@(");
    514  1.1  christos       (*info->print_address_func) (disp, info);
    515  1.1  christos     }
    516  1.1  christos   else
    517  1.1  christos     {
    518  1.1  christos       char buf[50];
    519  1.1  christos 
    520  1.1  christos       if (regno == -2)
    521  1.1  christos 	(*info->fprintf_func) (info->stream, "@(");
    522  1.1  christos       else if (regno == -3)
    523  1.1  christos 	(*info->fprintf_func) (info->stream, "%%zpc@(");
    524  1.1  christos       else
    525  1.1  christos 	(*info->fprintf_func) (info->stream, "%s@(", reg_names[regno]);
    526  1.1  christos 
    527  1.1  christos       sprintf_vma (buf, disp);
    528  1.1  christos       (*info->fprintf_func) (info->stream, "%s", buf);
    529  1.1  christos     }
    530  1.1  christos }
    531  1.1  christos 
    532  1.1  christos /* Print an indexed argument.  The base register is BASEREG (-1 for pc).
    533  1.1  christos    P points to extension word, in buffer.
    534  1.1  christos    ADDR is the nominal core address of that extension word.
    535  1.1  christos    Returns NULL upon error.  */
    536  1.1  christos 
    537  1.1  christos static unsigned char *
    538  1.1  christos print_indexed (int basereg,
    539  1.1  christos 	       unsigned char *p,
    540  1.1  christos 	       bfd_vma addr,
    541  1.1  christos 	       disassemble_info *info)
    542  1.1  christos {
    543  1.1  christos   int word;
    544  1.1  christos   static char *const scales[] = { "", ":2", ":4", ":8" };
    545  1.1  christos   bfd_vma base_disp;
    546  1.1  christos   bfd_vma outer_disp;
    547  1.1  christos   char buf[40];
    548  1.1  christos   char vmabuf[50];
    549  1.1  christos 
    550  1.1  christos   NEXTWORD (p, word, NULL);
    551  1.1  christos 
    552  1.1  christos   /* Generate the text for the index register.
    553  1.1  christos      Where this will be output is not yet determined.  */
    554  1.1  christos   sprintf (buf, "%s:%c%s",
    555  1.1  christos 	   reg_names[(word >> 12) & 0xf],
    556  1.1  christos 	   (word & 0x800) ? 'l' : 'w',
    557  1.1  christos 	   scales[(word >> 9) & 3]);
    558  1.1  christos 
    559  1.1  christos   /* Handle the 68000 style of indexing.  */
    560  1.1  christos 
    561  1.1  christos   if ((word & 0x100) == 0)
    562  1.1  christos     {
    563  1.1  christos       base_disp = word & 0xff;
    564  1.1  christos       if ((base_disp & 0x80) != 0)
    565  1.1  christos 	base_disp -= 0x100;
    566  1.1  christos       if (basereg == -1)
    567  1.1  christos 	base_disp += addr;
    568  1.1  christos       print_base (basereg, base_disp, info);
    569  1.1  christos       (*info->fprintf_func) (info->stream, ",%s)", buf);
    570  1.1  christos       return p;
    571  1.1  christos     }
    572  1.1  christos 
    573  1.1  christos   /* Handle the generalized kind.  */
    574  1.1  christos   /* First, compute the displacement to add to the base register.  */
    575  1.1  christos   if (word & 0200)
    576  1.1  christos     {
    577  1.1  christos       if (basereg == -1)
    578  1.1  christos 	basereg = -3;
    579  1.1  christos       else
    580  1.1  christos 	basereg = -2;
    581  1.1  christos     }
    582  1.1  christos   if (word & 0100)
    583  1.1  christos     buf[0] = '\0';
    584  1.1  christos   base_disp = 0;
    585  1.1  christos   switch ((word >> 4) & 3)
    586  1.1  christos     {
    587  1.1  christos     case 2:
    588  1.1  christos       NEXTWORD (p, base_disp, NULL);
    589  1.1  christos       break;
    590  1.1  christos     case 3:
    591  1.1  christos       NEXTLONG (p, base_disp, NULL);
    592  1.1  christos     }
    593  1.1  christos   if (basereg == -1)
    594  1.1  christos     base_disp += addr;
    595  1.1  christos 
    596  1.1  christos   /* Handle single-level case (not indirect).  */
    597  1.1  christos   if ((word & 7) == 0)
    598  1.1  christos     {
    599  1.1  christos       print_base (basereg, base_disp, info);
    600  1.1  christos       if (buf[0] != '\0')
    601  1.1  christos 	(*info->fprintf_func) (info->stream, ",%s", buf);
    602  1.1  christos       (*info->fprintf_func) (info->stream, ")");
    603  1.1  christos       return p;
    604  1.1  christos     }
    605  1.1  christos 
    606  1.1  christos   /* Two level.  Compute displacement to add after indirection.  */
    607  1.1  christos   outer_disp = 0;
    608  1.1  christos   switch (word & 3)
    609  1.1  christos     {
    610  1.1  christos     case 2:
    611  1.1  christos       NEXTWORD (p, outer_disp, NULL);
    612  1.1  christos       break;
    613  1.1  christos     case 3:
    614  1.1  christos       NEXTLONG (p, outer_disp, NULL);
    615  1.1  christos     }
    616  1.1  christos 
    617  1.1  christos   print_base (basereg, base_disp, info);
    618  1.1  christos   if ((word & 4) == 0 && buf[0] != '\0')
    619  1.1  christos     {
    620  1.1  christos       (*info->fprintf_func) (info->stream, ",%s", buf);
    621  1.1  christos       buf[0] = '\0';
    622  1.1  christos     }
    623  1.1  christos   sprintf_vma (vmabuf, outer_disp);
    624  1.1  christos   (*info->fprintf_func) (info->stream, ")@(%s", vmabuf);
    625  1.1  christos   if (buf[0] != '\0')
    626  1.1  christos     (*info->fprintf_func) (info->stream, ",%s", buf);
    627  1.1  christos   (*info->fprintf_func) (info->stream, ")");
    628  1.1  christos 
    629  1.1  christos   return p;
    630  1.1  christos }
    631  1.1  christos 
    632  1.1  christos #define FETCH_ARG(size, val)				\
    633  1.1  christos   do							\
    634  1.1  christos     {							\
    635  1.7  christos       val = fetch_arg (buffer, place, size, info);	\
    636  1.1  christos       if (val < 0)					\
    637  1.1  christos 	return PRINT_INSN_ARG_MEMORY_ERROR;		\
    638  1.1  christos     }							\
    639  1.1  christos   while (0)
    640  1.7  christos 
    641  1.7  christos /* Returns number of bytes "eaten" by the operand, or
    642  1.1  christos    return enum print_insn_arg_error.  ADDR is the pc for this arg to be
    643  1.1  christos    relative to.  */
    644  1.1  christos 
    645  1.1  christos static int
    646  1.1  christos print_insn_arg (const char *d,
    647  1.1  christos 		unsigned char *buffer,
    648  1.1  christos 		unsigned char *p0,
    649  1.1  christos 		bfd_vma addr,
    650  1.1  christos 		disassemble_info *info)
    651  1.1  christos {
    652  1.1  christos   int val = 0;
    653  1.1  christos   int place = d[1];
    654  1.1  christos   unsigned char *p = p0;
    655  1.1  christos   int regno;
    656  1.1  christos   const char *regname;
    657  1.1  christos   unsigned char *p1;
    658  1.1  christos   double flval;
    659  1.1  christos   int flt_p;
    660  1.1  christos   bfd_signed_vma disp;
    661  1.1  christos   unsigned int uval;
    662  1.1  christos 
    663  1.1  christos   switch (*d)
    664  1.1  christos     {
    665  1.1  christos     case 'c':		/* Cache identifier.  */
    666  1.1  christos       {
    667  1.1  christos         static char *const cacheFieldName[] = { "nc", "dc", "ic", "bc" };
    668  1.1  christos         FETCH_ARG (2, val);
    669  1.1  christos 	(*info->fprintf_func) (info->stream, "%s", cacheFieldName[val]);
    670  1.1  christos         break;
    671  1.1  christos       }
    672  1.1  christos 
    673  1.1  christos     case 'a':		/* Address register indirect only. Cf. case '+'.  */
    674  1.1  christos       {
    675  1.1  christos 	FETCH_ARG (3, val);
    676  1.1  christos 	(*info->fprintf_func) (info->stream, "%s@", reg_names[val + 8]);
    677  1.1  christos         break;
    678  1.1  christos       }
    679  1.1  christos 
    680  1.1  christos     case '_':		/* 32-bit absolute address for move16.  */
    681  1.1  christos       {
    682  1.1  christos         NEXTULONG (p, uval);
    683  1.1  christos 	(*info->print_address_func) (uval, info);
    684  1.1  christos         break;
    685  1.1  christos       }
    686  1.1  christos 
    687  1.1  christos     case 'C':
    688  1.1  christos       (*info->fprintf_func) (info->stream, "%%ccr");
    689  1.1  christos       break;
    690  1.1  christos 
    691  1.1  christos     case 'S':
    692  1.1  christos       (*info->fprintf_func) (info->stream, "%%sr");
    693  1.1  christos       break;
    694  1.1  christos 
    695  1.1  christos     case 'U':
    696  1.1  christos       (*info->fprintf_func) (info->stream, "%%usp");
    697  1.1  christos       break;
    698  1.1  christos 
    699  1.1  christos     case 'E':
    700  1.1  christos       (*info->fprintf_func) (info->stream, "%%acc");
    701  1.1  christos       break;
    702  1.1  christos 
    703  1.1  christos     case 'G':
    704  1.1  christos       (*info->fprintf_func) (info->stream, "%%macsr");
    705  1.1  christos       break;
    706  1.1  christos 
    707  1.1  christos     case 'H':
    708  1.1  christos       (*info->fprintf_func) (info->stream, "%%mask");
    709  1.1  christos       break;
    710  1.1  christos 
    711  1.1  christos     case 'J':
    712  1.1  christos       {
    713  1.1  christos 	/* FIXME: There's a problem here, different m68k processors call the
    714  1.1  christos 	   same address different names.  The tables below try to get it right
    715  1.1  christos 	   using info->mach, but only for v4e.  */
    716  1.1  christos 	struct regname { char * name; int value; };
    717  1.1  christos 	static const struct regname names[] =
    718  1.1  christos 	  {
    719  1.1  christos 	    {"%sfc", 0x000}, {"%dfc", 0x001}, {"%cacr", 0x002},
    720  1.1  christos 	    {"%tc",  0x003}, {"%itt0",0x004}, {"%itt1", 0x005},
    721  1.1  christos 	    {"%dtt0",0x006}, {"%dtt1",0x007}, {"%buscr",0x008},
    722  1.1  christos 	    {"%rgpiobar", 0x009}, {"%acr4",0x00c},
    723  1.1  christos 	    {"%acr5",0x00d}, {"%acr6",0x00e}, {"%acr7", 0x00f},
    724  1.1  christos 	    {"%usp", 0x800}, {"%vbr", 0x801}, {"%caar", 0x802},
    725  1.1  christos 	    {"%msp", 0x803}, {"%isp", 0x804},
    726  1.1  christos 	    {"%pc", 0x80f},
    727  1.1  christos 	    /* Reg c04 is sometimes called flashbar or rambar.
    728  1.1  christos 	       Reg c05 is also sometimes called rambar.  */
    729  1.1  christos 	    {"%rambar0", 0xc04}, {"%rambar1", 0xc05},
    730  1.1  christos 
    731  1.1  christos 	    /* reg c0e is sometimes called mbar2 or secmbar.
    732  1.1  christos 	       reg c0f is sometimes called mbar.  */
    733  1.1  christos 	    {"%mbar0", 0xc0e}, {"%mbar1", 0xc0f},
    734  1.1  christos 
    735  1.1  christos 	    /* Should we be calling this psr like we do in case 'Y'?  */
    736  1.1  christos 	    {"%mmusr",0x805},
    737  1.1  christos 
    738  1.1  christos 	    {"%urp", 0x806}, {"%srp", 0x807}, {"%pcr", 0x808},
    739  1.1  christos 
    740  1.1  christos 	    /* Fido added these.  */
    741  1.1  christos 	    {"%cac", 0xffe}, {"%mbo", 0xfff}
    742  1.1  christos 	};
    743  1.1  christos 	/* Alternate names for v4e (MCF5407/5445x/MCF547x/MCF548x), at least.  */
    744  1.1  christos 	static const struct regname names_v4e[] =
    745  1.1  christos 	  {
    746  1.1  christos 	    {"%asid",0x003}, {"%acr0",0x004}, {"%acr1",0x005},
    747  1.1  christos 	    {"%acr2",0x006}, {"%acr3",0x007}, {"%mmubar",0x008},
    748  1.1  christos 	  };
    749  1.1  christos 	unsigned int arch_mask;
    750  1.1  christos 
    751  1.1  christos 	arch_mask = bfd_m68k_mach_to_features (info->mach);
    752  1.1  christos 	FETCH_ARG (12, val);
    753  1.1  christos 	if (arch_mask & (mcfisa_b | mcfisa_c))
    754  1.1  christos 	  {
    755  1.1  christos 	    for (regno = ARRAY_SIZE (names_v4e); --regno >= 0;)
    756  1.1  christos 	      if (names_v4e[regno].value == val)
    757  1.1  christos 		{
    758  1.1  christos 		  (*info->fprintf_func) (info->stream, "%s", names_v4e[regno].name);
    759  1.1  christos 		  break;
    760  1.1  christos 		}
    761  1.1  christos 	    if (regno >= 0)
    762  1.1  christos 	      break;
    763  1.1  christos 	  }
    764  1.1  christos 	for (regno = ARRAY_SIZE (names) - 1; regno >= 0; regno--)
    765  1.1  christos 	  if (names[regno].value == val)
    766  1.1  christos 	    {
    767  1.1  christos 	      (*info->fprintf_func) (info->stream, "%s", names[regno].name);
    768  1.1  christos 	      break;
    769  1.1  christos 	    }
    770  1.1  christos 	if (regno < 0)
    771  1.1  christos 	  (*info->fprintf_func) (info->stream, "0x%x", val);
    772  1.1  christos       }
    773  1.1  christos       break;
    774  1.1  christos 
    775  1.1  christos     case 'Q':
    776  1.1  christos       FETCH_ARG (3, val);
    777  1.1  christos       /* 0 means 8, except for the bkpt instruction... */
    778  1.1  christos       if (val == 0 && d[1] != 's')
    779  1.1  christos 	val = 8;
    780  1.1  christos       (*info->fprintf_func) (info->stream, "#%d", val);
    781  1.1  christos       break;
    782  1.1  christos 
    783  1.1  christos     case 'x':
    784  1.1  christos       FETCH_ARG (3, val);
    785  1.1  christos       /* 0 means -1.  */
    786  1.1  christos       if (val == 0)
    787  1.1  christos 	val = -1;
    788  1.1  christos       (*info->fprintf_func) (info->stream, "#%d", val);
    789  1.1  christos       break;
    790  1.1  christos 
    791  1.1  christos     case 'j':
    792  1.1  christos       FETCH_ARG (3, val);
    793  1.1  christos       (*info->fprintf_func) (info->stream, "#%d", val+1);
    794  1.1  christos       break;
    795  1.1  christos 
    796  1.1  christos     case 'K':
    797  1.1  christos       FETCH_ARG (9, val);
    798  1.1  christos       (*info->fprintf_func) (info->stream, "#%d", val);
    799  1.1  christos       break;
    800  1.1  christos 
    801  1.1  christos     case 'M':
    802  1.1  christos       if (place == 'h')
    803  1.1  christos 	{
    804  1.1  christos 	  static char *const scalefactor_name[] = { "<<", ">>" };
    805  1.1  christos 
    806  1.1  christos 	  FETCH_ARG (1, val);
    807  1.1  christos 	  (*info->fprintf_func) (info->stream, "%s", scalefactor_name[val]);
    808  1.1  christos 	}
    809  1.1  christos       else
    810  1.1  christos 	{
    811  1.1  christos 	  FETCH_ARG (8, val);
    812  1.1  christos 	  if (val & 0x80)
    813  1.1  christos 	    val = val - 0x100;
    814  1.1  christos 	  (*info->fprintf_func) (info->stream, "#%d", val);
    815  1.1  christos 	}
    816  1.1  christos       break;
    817  1.1  christos 
    818  1.1  christos     case 'T':
    819  1.1  christos       FETCH_ARG (4, val);
    820  1.1  christos       (*info->fprintf_func) (info->stream, "#%d", val);
    821  1.1  christos       break;
    822  1.1  christos 
    823  1.1  christos     case 'D':
    824  1.1  christos       FETCH_ARG (3, val);
    825  1.1  christos       (*info->fprintf_func) (info->stream, "%s", reg_names[val]);
    826  1.1  christos       break;
    827  1.1  christos 
    828  1.1  christos     case 'A':
    829  1.1  christos       FETCH_ARG (3, val);
    830  1.1  christos       (*info->fprintf_func) (info->stream, "%s", reg_names[val + 010]);
    831  1.1  christos       break;
    832  1.1  christos 
    833  1.1  christos     case 'R':
    834  1.1  christos       FETCH_ARG (4, val);
    835  1.1  christos       (*info->fprintf_func) (info->stream, "%s", reg_names[val]);
    836  1.1  christos       break;
    837  1.1  christos 
    838  1.1  christos     case 'r':
    839  1.1  christos       FETCH_ARG (4, regno);
    840  1.1  christos       if (regno > 7)
    841  1.1  christos 	(*info->fprintf_func) (info->stream, "%s@", reg_names[regno]);
    842  1.1  christos       else
    843  1.1  christos 	(*info->fprintf_func) (info->stream, "@(%s)", reg_names[regno]);
    844  1.1  christos       break;
    845  1.1  christos 
    846  1.1  christos     case 'F':
    847  1.1  christos       FETCH_ARG (3, val);
    848  1.1  christos       (*info->fprintf_func) (info->stream, "%%fp%d", val);
    849  1.1  christos       break;
    850  1.1  christos 
    851  1.1  christos     case 'O':
    852  1.1  christos       FETCH_ARG (6, val);
    853  1.1  christos       if (val & 0x20)
    854  1.1  christos 	(*info->fprintf_func) (info->stream, "%s", reg_names[val & 7]);
    855  1.1  christos       else
    856  1.1  christos 	(*info->fprintf_func) (info->stream, "%d", val);
    857  1.1  christos       break;
    858  1.1  christos 
    859  1.1  christos     case '+':
    860  1.1  christos       FETCH_ARG (3, val);
    861  1.1  christos       (*info->fprintf_func) (info->stream, "%s@+", reg_names[val + 8]);
    862  1.1  christos       break;
    863  1.1  christos 
    864  1.1  christos     case '-':
    865  1.1  christos       FETCH_ARG (3, val);
    866  1.1  christos       (*info->fprintf_func) (info->stream, "%s@-", reg_names[val + 8]);
    867  1.1  christos       break;
    868  1.1  christos 
    869  1.1  christos     case 'k':
    870  1.1  christos       if (place == 'k')
    871  1.1  christos 	{
    872  1.1  christos 	  FETCH_ARG (3, val);
    873  1.1  christos 	  (*info->fprintf_func) (info->stream, "{%s}", reg_names[val]);
    874  1.1  christos 	}
    875  1.1  christos       else if (place == 'C')
    876  1.1  christos 	{
    877  1.1  christos 	  FETCH_ARG (7, val);
    878  1.1  christos 	  if (val > 63)		/* This is a signed constant.  */
    879  1.1  christos 	    val -= 128;
    880  1.1  christos 	  (*info->fprintf_func) (info->stream, "{#%d}", val);
    881  1.7  christos 	}
    882  1.1  christos       else
    883  1.1  christos 	return PRINT_INSN_ARG_INVALID_OPERAND;
    884  1.1  christos       break;
    885  1.1  christos 
    886  1.1  christos     case '#':
    887  1.1  christos     case '^':
    888  1.1  christos       p1 = buffer + (*d == '#' ? 2 : 4);
    889  1.1  christos       if (place == 's')
    890  1.1  christos 	FETCH_ARG (4, val);
    891  1.1  christos       else if (place == 'C')
    892  1.1  christos 	FETCH_ARG (7, val);
    893  1.1  christos       else if (place == '8')
    894  1.1  christos 	FETCH_ARG (3, val);
    895  1.1  christos       else if (place == '3')
    896  1.1  christos 	FETCH_ARG (8, val);
    897  1.1  christos       else if (place == 'b')
    898  1.7  christos 	NEXTBYTE (p1, val);
    899  1.1  christos       else if (place == 'w' || place == 'W')
    900  1.7  christos 	NEXTWORD (p1, val, PRINT_INSN_ARG_MEMORY_ERROR);
    901  1.1  christos       else if (place == 'l')
    902  1.7  christos 	NEXTLONG (p1, val, PRINT_INSN_ARG_MEMORY_ERROR);
    903  1.1  christos       else
    904  1.1  christos 	return PRINT_INSN_ARG_INVALID_OP_TABLE;
    905  1.1  christos 
    906  1.1  christos       (*info->fprintf_func) (info->stream, "#%d", val);
    907  1.1  christos       break;
    908  1.1  christos 
    909  1.1  christos     case 'B':
    910  1.1  christos       if (place == 'b')
    911  1.1  christos 	NEXTBYTE (p, disp);
    912  1.1  christos       else if (place == 'B')
    913  1.7  christos 	disp = COERCE_SIGNED_CHAR (buffer[1]);
    914  1.1  christos       else if (place == 'w' || place == 'W')
    915  1.7  christos 	NEXTWORD (p, disp, PRINT_INSN_ARG_MEMORY_ERROR);
    916  1.1  christos       else if (place == 'l' || place == 'L' || place == 'C')
    917  1.1  christos 	NEXTLONG (p, disp, PRINT_INSN_ARG_MEMORY_ERROR);
    918  1.1  christos       else if (place == 'g')
    919  1.1  christos 	{
    920  1.7  christos 	  NEXTBYTE (buffer, disp);
    921  1.1  christos 	  if (disp == 0)
    922  1.7  christos 	    NEXTWORD (p, disp, PRINT_INSN_ARG_MEMORY_ERROR);
    923  1.1  christos 	  else if (disp == -1)
    924  1.1  christos 	    NEXTLONG (p, disp, PRINT_INSN_ARG_MEMORY_ERROR);
    925  1.1  christos 	}
    926  1.1  christos       else if (place == 'c')
    927  1.7  christos 	{
    928  1.1  christos 	  if (buffer[1] & 0x40)		/* If bit six is one, long offset.  */
    929  1.7  christos 	    NEXTLONG (p, disp, PRINT_INSN_ARG_MEMORY_ERROR);
    930  1.1  christos 	  else
    931  1.1  christos 	    NEXTWORD (p, disp, PRINT_INSN_ARG_MEMORY_ERROR);
    932  1.7  christos 	}
    933  1.1  christos       else
    934  1.1  christos 	return PRINT_INSN_ARG_INVALID_OP_TABLE;
    935  1.1  christos 
    936  1.1  christos       (*info->print_address_func) (addr + disp, info);
    937  1.1  christos       break;
    938  1.1  christos 
    939  1.1  christos     case 'd':
    940  1.1  christos       {
    941  1.7  christos 	int val1;
    942  1.1  christos 
    943  1.1  christos 	NEXTWORD (p, val, PRINT_INSN_ARG_MEMORY_ERROR);
    944  1.1  christos 	FETCH_ARG (3, val1);
    945  1.1  christos 	(*info->fprintf_func) (info->stream, "%s@(%d)", reg_names[val1 + 8], val);
    946  1.1  christos 	break;
    947  1.1  christos       }
    948  1.1  christos 
    949  1.1  christos     case 's':
    950  1.1  christos       FETCH_ARG (3, val);
    951  1.1  christos       (*info->fprintf_func) (info->stream, "%s", fpcr_names[val]);
    952  1.1  christos       break;
    953  1.1  christos 
    954  1.1  christos     case 'e':
    955  1.1  christos       FETCH_ARG (2, val);
    956  1.1  christos       (*info->fprintf_func) (info->stream, "%%acc%d", val);
    957  1.1  christos       break;
    958  1.1  christos 
    959  1.1  christos     case 'g':
    960  1.1  christos       FETCH_ARG (1, val);
    961  1.1  christos       (*info->fprintf_func) (info->stream, "%%accext%s", val == 0 ? "01" : "23");
    962  1.1  christos       break;
    963  1.1  christos 
    964  1.1  christos     case 'i':
    965  1.1  christos       FETCH_ARG (2, val);
    966  1.1  christos       if (val == 1)
    967  1.1  christos 	(*info->fprintf_func) (info->stream, "<<");
    968  1.1  christos       else if (val == 3)
    969  1.7  christos 	(*info->fprintf_func) (info->stream, ">>");
    970  1.1  christos       else
    971  1.1  christos 	return PRINT_INSN_ARG_INVALID_OPERAND;
    972  1.1  christos       break;
    973  1.1  christos 
    974  1.1  christos     case 'I':
    975  1.1  christos       /* Get coprocessor ID... */
    976  1.7  christos       val = fetch_arg (buffer, 'd', 3, info);
    977  1.1  christos       if (val < 0)
    978  1.1  christos 	return PRINT_INSN_ARG_MEMORY_ERROR;
    979  1.1  christos       if (val != 1)				/* Unusual coprocessor ID?  */
    980  1.1  christos 	(*info->fprintf_func) (info->stream, "(cpid=%d) ", val);
    981  1.1  christos       break;
    982  1.1  christos 
    983  1.1  christos     case '4':
    984  1.1  christos     case '*':
    985  1.1  christos     case '~':
    986  1.1  christos     case '%':
    987  1.1  christos     case ';':
    988  1.1  christos     case '@':
    989  1.1  christos     case '!':
    990  1.1  christos     case '$':
    991  1.1  christos     case '?':
    992  1.1  christos     case '/':
    993  1.1  christos     case '&':
    994  1.1  christos     case '|':
    995  1.1  christos     case '<':
    996  1.1  christos     case '>':
    997  1.1  christos     case 'm':
    998  1.1  christos     case 'n':
    999  1.1  christos     case 'o':
   1000  1.1  christos     case 'p':
   1001  1.1  christos     case 'q':
   1002  1.1  christos     case 'v':
   1003  1.1  christos     case 'b':
   1004  1.1  christos     case 'w':
   1005  1.1  christos     case 'y':
   1006  1.1  christos     case 'z':
   1007  1.1  christos       if (place == 'd')
   1008  1.1  christos 	{
   1009  1.7  christos 	  val = fetch_arg (buffer, 'x', 6, info);
   1010  1.1  christos 	  if (val < 0)
   1011  1.1  christos 	    return PRINT_INSN_ARG_MEMORY_ERROR;
   1012  1.1  christos 	  val = ((val & 7) << 3) + ((val >> 3) & 7);
   1013  1.1  christos 	}
   1014  1.1  christos       else
   1015  1.1  christos 	{
   1016  1.7  christos 	  val = fetch_arg (buffer, 's', 6, info);
   1017  1.1  christos 	  if (val < 0)
   1018  1.1  christos 	    return PRINT_INSN_ARG_MEMORY_ERROR;
   1019  1.1  christos 	}
   1020  1.1  christos 
   1021  1.7  christos       /* If the <ea> is invalid for *d, then reject this match.  */
   1022  1.1  christos       if (!m68k_valid_ea (*d, val))
   1023  1.1  christos 	return PRINT_INSN_ARG_INVALID_OPERAND;
   1024  1.1  christos 
   1025  1.1  christos       /* Get register number assuming address register.  */
   1026  1.1  christos       regno = (val & 7) + 8;
   1027  1.1  christos       regname = reg_names[regno];
   1028  1.1  christos       switch (val >> 3)
   1029  1.1  christos 	{
   1030  1.1  christos 	case 0:
   1031  1.1  christos 	  (*info->fprintf_func) (info->stream, "%s", reg_names[val]);
   1032  1.1  christos 	  break;
   1033  1.1  christos 
   1034  1.1  christos 	case 1:
   1035  1.1  christos 	  (*info->fprintf_func) (info->stream, "%s", regname);
   1036  1.1  christos 	  break;
   1037  1.1  christos 
   1038  1.1  christos 	case 2:
   1039  1.1  christos 	  (*info->fprintf_func) (info->stream, "%s@", regname);
   1040  1.1  christos 	  break;
   1041  1.1  christos 
   1042  1.1  christos 	case 3:
   1043  1.1  christos 	  (*info->fprintf_func) (info->stream, "%s@+", regname);
   1044  1.1  christos 	  break;
   1045  1.1  christos 
   1046  1.1  christos 	case 4:
   1047  1.1  christos 	  (*info->fprintf_func) (info->stream, "%s@-", regname);
   1048  1.1  christos 	  break;
   1049  1.7  christos 
   1050  1.1  christos 	case 5:
   1051  1.1  christos 	  NEXTWORD (p, val, PRINT_INSN_ARG_MEMORY_ERROR);
   1052  1.1  christos 	  (*info->fprintf_func) (info->stream, "%s@(%d)", regname, val);
   1053  1.1  christos 	  break;
   1054  1.1  christos 
   1055  1.1  christos 	case 6:
   1056  1.7  christos 	  p = print_indexed (regno, p, addr, info);
   1057  1.1  christos 	  if (p == NULL)
   1058  1.1  christos 	    return PRINT_INSN_ARG_MEMORY_ERROR;
   1059  1.1  christos 	  break;
   1060  1.1  christos 
   1061  1.1  christos 	case 7:
   1062  1.1  christos 	  switch (val & 7)
   1063  1.7  christos 	    {
   1064  1.1  christos 	    case 0:
   1065  1.1  christos 	      NEXTWORD (p, val, PRINT_INSN_ARG_MEMORY_ERROR);
   1066  1.1  christos 	      (*info->print_address_func) (val, info);
   1067  1.1  christos 	      break;
   1068  1.1  christos 
   1069  1.1  christos 	    case 1:
   1070  1.1  christos 	      NEXTULONG (p, uval);
   1071  1.1  christos 	      (*info->print_address_func) (uval, info);
   1072  1.1  christos 	      break;
   1073  1.7  christos 
   1074  1.1  christos 	    case 2:
   1075  1.1  christos 	      NEXTWORD (p, val, PRINT_INSN_ARG_MEMORY_ERROR);
   1076  1.1  christos 	      (*info->fprintf_func) (info->stream, "%%pc@(");
   1077  1.1  christos 	      (*info->print_address_func) (addr + val, info);
   1078  1.1  christos 	      (*info->fprintf_func) (info->stream, ")");
   1079  1.1  christos 	      break;
   1080  1.1  christos 
   1081  1.1  christos 	    case 3:
   1082  1.7  christos 	      p = print_indexed (-1, p, addr, info);
   1083  1.1  christos 	      if (p == NULL)
   1084  1.1  christos 		return PRINT_INSN_ARG_MEMORY_ERROR;
   1085  1.1  christos 	      break;
   1086  1.1  christos 
   1087  1.1  christos 	    case 4:
   1088  1.1  christos 	      flt_p = 1;	/* Assume it's a float... */
   1089  1.1  christos 	      switch (place)
   1090  1.1  christos 	      {
   1091  1.1  christos 		case 'b':
   1092  1.1  christos 		  NEXTBYTE (p, val);
   1093  1.1  christos 		  flt_p = 0;
   1094  1.1  christos 		  break;
   1095  1.7  christos 
   1096  1.1  christos 		case 'w':
   1097  1.1  christos 		  NEXTWORD (p, val, PRINT_INSN_ARG_MEMORY_ERROR);
   1098  1.1  christos 		  flt_p = 0;
   1099  1.1  christos 		  break;
   1100  1.7  christos 
   1101  1.1  christos 		case 'l':
   1102  1.1  christos 		  NEXTLONG (p, val, PRINT_INSN_ARG_MEMORY_ERROR);
   1103  1.1  christos 		  flt_p = 0;
   1104  1.1  christos 		  break;
   1105  1.1  christos 
   1106  1.1  christos 		case 'f':
   1107  1.1  christos 		  NEXTSINGLE (flval, p);
   1108  1.1  christos 		  break;
   1109  1.1  christos 
   1110  1.1  christos 		case 'F':
   1111  1.1  christos 		  NEXTDOUBLE (flval, p);
   1112  1.1  christos 		  break;
   1113  1.1  christos 
   1114  1.1  christos 		case 'x':
   1115  1.1  christos 		  NEXTEXTEND (flval, p);
   1116  1.1  christos 		  break;
   1117  1.1  christos 
   1118  1.1  christos 		case 'p':
   1119  1.1  christos 		  NEXTPACKED (p, flval);
   1120  1.1  christos 		  break;
   1121  1.7  christos 
   1122  1.1  christos 		default:
   1123  1.1  christos 		  return PRINT_INSN_ARG_INVALID_OPERAND;
   1124  1.1  christos 	      }
   1125  1.1  christos 	      if (flt_p)	/* Print a float? */
   1126  1.1  christos 		(*info->fprintf_func) (info->stream, "#0e%g", flval);
   1127  1.1  christos 	      else
   1128  1.1  christos 		(*info->fprintf_func) (info->stream, "#%d", val);
   1129  1.1  christos 	      break;
   1130  1.7  christos 
   1131  1.1  christos 	    default:
   1132  1.1  christos 	      return PRINT_INSN_ARG_INVALID_OPERAND;
   1133  1.1  christos 	    }
   1134  1.1  christos 	}
   1135  1.1  christos 
   1136  1.1  christos       /* If place is '/', then this is the case of the mask bit for
   1137  1.1  christos 	 mac/emac loads. Now that the arg has been printed, grab the
   1138  1.1  christos 	 mask bit and if set, add a '&' to the arg.  */
   1139  1.1  christos       if (place == '/')
   1140  1.1  christos 	{
   1141  1.1  christos 	  FETCH_ARG (1, val);
   1142  1.1  christos 	  if (val)
   1143  1.1  christos 	    info->fprintf_func (info->stream, "&");
   1144  1.1  christos 	}
   1145  1.1  christos       break;
   1146  1.1  christos 
   1147  1.1  christos     case 'L':
   1148  1.1  christos     case 'l':
   1149  1.1  christos 	if (place == 'w')
   1150  1.1  christos 	  {
   1151  1.7  christos 	    char doneany;
   1152  1.1  christos 	    p1 = buffer + 2;
   1153  1.1  christos 	    NEXTWORD (p1, val, PRINT_INSN_ARG_MEMORY_ERROR);
   1154  1.1  christos 	    /* Move the pointer ahead if this point is farther ahead
   1155  1.1  christos 	       than the last.  */
   1156  1.1  christos 	    p = p1 > p ? p1 : p;
   1157  1.1  christos 	    if (val == 0)
   1158  1.1  christos 	      {
   1159  1.1  christos 		(*info->fprintf_func) (info->stream, "#0");
   1160  1.1  christos 		break;
   1161  1.1  christos 	      }
   1162  1.1  christos 	    if (*d == 'l')
   1163  1.1  christos 	      {
   1164  1.1  christos 		int newval = 0;
   1165  1.1  christos 
   1166  1.1  christos 		for (regno = 0; regno < 16; ++regno)
   1167  1.1  christos 		  if (val & (0x8000 >> regno))
   1168  1.1  christos 		    newval |= 1 << regno;
   1169  1.1  christos 		val = newval;
   1170  1.1  christos 	      }
   1171  1.1  christos 	    val &= 0xffff;
   1172  1.1  christos 	    doneany = 0;
   1173  1.1  christos 	    for (regno = 0; regno < 16; ++regno)
   1174  1.1  christos 	      if (val & (1 << regno))
   1175  1.1  christos 		{
   1176  1.1  christos 		  int first_regno;
   1177  1.1  christos 
   1178  1.1  christos 		  if (doneany)
   1179  1.1  christos 		    (*info->fprintf_func) (info->stream, "/");
   1180  1.1  christos 		  doneany = 1;
   1181  1.1  christos 		  (*info->fprintf_func) (info->stream, "%s", reg_names[regno]);
   1182  1.1  christos 		  first_regno = regno;
   1183  1.1  christos 		  while (val & (1 << (regno + 1)))
   1184  1.1  christos 		    ++regno;
   1185  1.1  christos 		  if (regno > first_regno)
   1186  1.1  christos 		    (*info->fprintf_func) (info->stream, "-%s",
   1187  1.1  christos 					   reg_names[regno]);
   1188  1.1  christos 		}
   1189  1.1  christos 	  }
   1190  1.1  christos 	else if (place == '3')
   1191  1.1  christos 	  {
   1192  1.1  christos 	    /* `fmovem' insn.  */
   1193  1.1  christos 	    char doneany;
   1194  1.1  christos 
   1195  1.1  christos 	    FETCH_ARG (8, val);
   1196  1.1  christos 	    if (val == 0)
   1197  1.1  christos 	      {
   1198  1.1  christos 		(*info->fprintf_func) (info->stream, "#0");
   1199  1.1  christos 		break;
   1200  1.1  christos 	      }
   1201  1.1  christos 	    if (*d == 'l')
   1202  1.1  christos 	      {
   1203  1.1  christos 		int newval = 0;
   1204  1.1  christos 
   1205  1.1  christos 		for (regno = 0; regno < 8; ++regno)
   1206  1.1  christos 		  if (val & (0x80 >> regno))
   1207  1.1  christos 		    newval |= 1 << regno;
   1208  1.1  christos 		val = newval;
   1209  1.1  christos 	      }
   1210  1.1  christos 	    val &= 0xff;
   1211  1.1  christos 	    doneany = 0;
   1212  1.1  christos 	    for (regno = 0; regno < 8; ++regno)
   1213  1.1  christos 	      if (val & (1 << regno))
   1214  1.1  christos 		{
   1215  1.1  christos 		  int first_regno;
   1216  1.1  christos 		  if (doneany)
   1217  1.1  christos 		    (*info->fprintf_func) (info->stream, "/");
   1218  1.1  christos 		  doneany = 1;
   1219  1.1  christos 		  (*info->fprintf_func) (info->stream, "%%fp%d", regno);
   1220  1.1  christos 		  first_regno = regno;
   1221  1.1  christos 		  while (val & (1 << (regno + 1)))
   1222  1.1  christos 		    ++regno;
   1223  1.1  christos 		  if (regno > first_regno)
   1224  1.1  christos 		    (*info->fprintf_func) (info->stream, "-%%fp%d", regno);
   1225  1.1  christos 		}
   1226  1.1  christos 	  }
   1227  1.1  christos 	else if (place == '8')
   1228  1.1  christos 	  {
   1229  1.1  christos 	    FETCH_ARG (3, val);
   1230  1.1  christos 	    /* fmoveml for FP status registers.  */
   1231  1.1  christos 	    (*info->fprintf_func) (info->stream, "%s", fpcr_names[val]);
   1232  1.7  christos 	  }
   1233  1.1  christos 	else
   1234  1.1  christos 	  return PRINT_INSN_ARG_INVALID_OP_TABLE;
   1235  1.1  christos       break;
   1236  1.1  christos 
   1237  1.7  christos     case 'X':
   1238  1.1  christos       place = '8';
   1239  1.1  christos       /* Fall through.  */
   1240  1.1  christos     case 'Y':
   1241  1.1  christos     case 'Z':
   1242  1.1  christos     case 'W':
   1243  1.1  christos     case '0':
   1244  1.1  christos     case '1':
   1245  1.1  christos     case '2':
   1246  1.1  christos     case '3':
   1247  1.1  christos       {
   1248  1.1  christos 	char *name = 0;
   1249  1.1  christos 
   1250  1.1  christos 	FETCH_ARG (5, val);
   1251  1.1  christos 	switch (val)
   1252  1.1  christos 	  {
   1253  1.1  christos 	  case 2: name = "%tt0"; break;
   1254  1.1  christos 	  case 3: name = "%tt1"; break;
   1255  1.1  christos 	  case 0x10: name = "%tc"; break;
   1256  1.1  christos 	  case 0x11: name = "%drp"; break;
   1257  1.1  christos 	  case 0x12: name = "%srp"; break;
   1258  1.1  christos 	  case 0x13: name = "%crp"; break;
   1259  1.1  christos 	  case 0x14: name = "%cal"; break;
   1260  1.1  christos 	  case 0x15: name = "%val"; break;
   1261  1.1  christos 	  case 0x16: name = "%scc"; break;
   1262  1.1  christos 	  case 0x17: name = "%ac"; break;
   1263  1.1  christos  	  case 0x18: name = "%psr"; break;
   1264  1.1  christos 	  case 0x19: name = "%pcsr"; break;
   1265  1.1  christos 	  case 0x1c:
   1266  1.1  christos 	  case 0x1d:
   1267  1.1  christos 	    {
   1268  1.1  christos 	      int break_reg = ((buffer[3] >> 2) & 7);
   1269  1.1  christos 
   1270  1.1  christos 	      (*info->fprintf_func)
   1271  1.1  christos 		(info->stream, val == 0x1c ? "%%bad%d" : "%%bac%d",
   1272  1.1  christos 		 break_reg);
   1273  1.1  christos 	    }
   1274  1.1  christos 	    break;
   1275  1.1  christos 	  default:
   1276  1.1  christos 	    (*info->fprintf_func) (info->stream, "<mmu register %d>", val);
   1277  1.1  christos 	  }
   1278  1.1  christos 	if (name)
   1279  1.1  christos 	  (*info->fprintf_func) (info->stream, "%s", name);
   1280  1.1  christos       }
   1281  1.1  christos       break;
   1282  1.1  christos 
   1283  1.1  christos     case 'f':
   1284  1.1  christos       {
   1285  1.1  christos 	int fc;
   1286  1.1  christos 
   1287  1.1  christos 	FETCH_ARG (5, fc);
   1288  1.1  christos 	if (fc == 1)
   1289  1.1  christos 	  (*info->fprintf_func) (info->stream, "%%dfc");
   1290  1.1  christos 	else if (fc == 0)
   1291  1.1  christos 	  (*info->fprintf_func) (info->stream, "%%sfc");
   1292  1.1  christos 	else
   1293  1.1  christos 	  /* xgettext:c-format */
   1294  1.1  christos 	  (*info->fprintf_func) (info->stream, _("<function code %d>"), fc);
   1295  1.1  christos       }
   1296  1.1  christos       break;
   1297  1.1  christos 
   1298  1.1  christos     case 'V':
   1299  1.1  christos       (*info->fprintf_func) (info->stream, "%%val");
   1300  1.1  christos       break;
   1301  1.1  christos 
   1302  1.1  christos     case 't':
   1303  1.1  christos       {
   1304  1.1  christos 	int level;
   1305  1.1  christos 
   1306  1.1  christos 	FETCH_ARG (3, level);
   1307  1.1  christos 	(*info->fprintf_func) (info->stream, "%d", level);
   1308  1.1  christos       }
   1309  1.1  christos       break;
   1310  1.1  christos 
   1311  1.1  christos     case 'u':
   1312  1.1  christos       {
   1313  1.1  christos 	short is_upper = 0;
   1314  1.1  christos 	int reg;
   1315  1.1  christos 
   1316  1.1  christos 	FETCH_ARG (5, reg);
   1317  1.1  christos 	if (reg & 0x10)
   1318  1.1  christos 	  {
   1319  1.1  christos 	    is_upper = 1;
   1320  1.1  christos 	    reg &= 0xf;
   1321  1.1  christos 	  }
   1322  1.1  christos 	(*info->fprintf_func) (info->stream, "%s%s",
   1323  1.1  christos 			       reg_half_names[reg],
   1324  1.1  christos 			       is_upper ? "u" : "l");
   1325  1.1  christos       }
   1326  1.1  christos       break;
   1327  1.7  christos 
   1328  1.1  christos     default:
   1329  1.1  christos       return PRINT_INSN_ARG_INVALID_OP_TABLE;
   1330  1.1  christos     }
   1331  1.1  christos 
   1332  1.1  christos   return p - p0;
   1333  1.1  christos }
   1334  1.7  christos 
   1335  1.7  christos /* Try to match the current instruction to best and if so, return the
   1336  1.1  christos    number of bytes consumed from the instruction stream, else zero.
   1337  1.1  christos    Return -1 on memory error.  */
   1338  1.1  christos 
   1339  1.1  christos static int
   1340  1.1  christos match_insn_m68k (bfd_vma memaddr,
   1341  1.1  christos 		 disassemble_info * info,
   1342  1.1  christos 		 const struct m68k_opcode * best)
   1343  1.1  christos {
   1344  1.1  christos   unsigned char *save_p;
   1345  1.1  christos   unsigned char *p;
   1346  1.1  christos   const char *d;
   1347  1.1  christos   const char *args = best->args;
   1348  1.1  christos 
   1349  1.1  christos   struct private *priv = (struct private *) info->private_data;
   1350  1.1  christos   bfd_byte *buffer = priv->the_buffer;
   1351  1.1  christos   fprintf_ftype save_printer = info->fprintf_func;
   1352  1.1  christos   void (* save_print_address) (bfd_vma, struct disassemble_info *)
   1353  1.1  christos     = info->print_address_func;
   1354  1.1  christos 
   1355  1.6  christos   if (*args == '.')
   1356  1.1  christos     args++;
   1357  1.1  christos 
   1358  1.1  christos   /* Point at first word of argument data,
   1359  1.1  christos      and at descriptor for first argument.  */
   1360  1.1  christos   p = buffer + 2;
   1361  1.1  christos 
   1362  1.1  christos   /* Figure out how long the fixed-size portion of the instruction is.
   1363  1.1  christos      The only place this is stored in the opcode table is
   1364  1.1  christos      in the arguments--look for arguments which specify fields in the 2nd
   1365  1.1  christos      or 3rd words of the instruction.  */
   1366  1.1  christos   for (d = args; *d; d += 2)
   1367  1.1  christos     {
   1368  1.1  christos       /* I don't think it is necessary to be checking d[0] here;
   1369  1.1  christos 	 I suspect all this could be moved to the case statement below.  */
   1370  1.1  christos       if (d[0] == '#')
   1371  1.1  christos 	{
   1372  1.1  christos 	  if (d[1] == 'l' && p - buffer < 6)
   1373  1.1  christos 	    p = buffer + 6;
   1374  1.1  christos 	  else if (p - buffer < 4 && d[1] != 'C' && d[1] != '8')
   1375  1.1  christos 	    p = buffer + 4;
   1376  1.1  christos 	}
   1377  1.1  christos 
   1378  1.1  christos       if ((d[0] == 'L' || d[0] == 'l') && d[1] == 'w' && p - buffer < 4)
   1379  1.1  christos 	p = buffer + 4;
   1380  1.1  christos 
   1381  1.1  christos       switch (d[1])
   1382  1.1  christos 	{
   1383  1.1  christos 	case '1':
   1384  1.1  christos 	case '2':
   1385  1.1  christos 	case '3':
   1386  1.1  christos 	case '7':
   1387  1.1  christos 	case '8':
   1388  1.1  christos 	case '9':
   1389  1.1  christos 	case 'i':
   1390  1.1  christos 	  if (p - buffer < 4)
   1391  1.1  christos 	    p = buffer + 4;
   1392  1.1  christos 	  break;
   1393  1.1  christos 	case '4':
   1394  1.1  christos 	case '5':
   1395  1.1  christos 	case '6':
   1396  1.1  christos 	  if (p - buffer < 6)
   1397  1.1  christos 	    p = buffer + 6;
   1398  1.1  christos 	  break;
   1399  1.1  christos 	default:
   1400  1.1  christos 	  break;
   1401  1.1  christos 	}
   1402  1.1  christos     }
   1403  1.1  christos 
   1404  1.1  christos   /* pflusha is an exceptions.  It takes no arguments but is two words
   1405  1.1  christos      long.  Recognize it by looking at the lower 16 bits of the mask.  */
   1406  1.1  christos   if (p - buffer < 4 && (best->match & 0xFFFF) != 0)
   1407  1.1  christos     p = buffer + 4;
   1408  1.1  christos 
   1409  1.1  christos   /* lpstop is another exception.  It takes a one word argument but is
   1410  1.1  christos      three words long.  */
   1411  1.1  christos   if (p - buffer < 6
   1412  1.1  christos       && (best->match & 0xffff) == 0xffff
   1413  1.1  christos       && args[0] == '#'
   1414  1.1  christos       && args[1] == 'w')
   1415  1.1  christos     {
   1416  1.1  christos       /* Copy the one word argument into the usual location for a one
   1417  1.1  christos 	 word argument, to simplify printing it.  We can get away with
   1418  1.1  christos 	 this because we know exactly what the second word is, and we
   1419  1.7  christos 	 aren't going to print anything based on it.  */
   1420  1.7  christos       p = buffer + 6;
   1421  1.1  christos       if (!FETCH_DATA (info, p))
   1422  1.1  christos 	return -1;
   1423  1.1  christos       buffer[2] = buffer[4];
   1424  1.1  christos       buffer[3] = buffer[5];
   1425  1.7  christos     }
   1426  1.7  christos 
   1427  1.1  christos   if (!FETCH_DATA (info, p))
   1428  1.1  christos     return -1;
   1429  1.1  christos 
   1430  1.1  christos   save_p = p;
   1431  1.1  christos   info->print_address_func = dummy_print_address;
   1432  1.1  christos   info->fprintf_func = (fprintf_ftype) dummy_printer;
   1433  1.1  christos 
   1434  1.1  christos   /* We scan the operands twice.  The first time we don't print anything,
   1435  1.1  christos      but look for errors.  */
   1436  1.1  christos   for (d = args; *d; d += 2)
   1437  1.1  christos     {
   1438  1.1  christos       int eaten = print_insn_arg (d, buffer, p, memaddr + (p - buffer), info);
   1439  1.1  christos 
   1440  1.7  christos       if (eaten >= 0)
   1441  1.7  christos 	p += eaten;
   1442  1.1  christos       else if (eaten == PRINT_INSN_ARG_INVALID_OPERAND
   1443  1.1  christos 	       || eaten == PRINT_INSN_ARG_MEMORY_ERROR)
   1444  1.1  christos 	{
   1445  1.7  christos 	  info->fprintf_func = save_printer;
   1446  1.1  christos 	  info->print_address_func = save_print_address;
   1447  1.1  christos 	  return eaten == PRINT_INSN_ARG_MEMORY_ERROR ? -1 : 0;
   1448  1.1  christos 	}
   1449  1.1  christos       else
   1450  1.1  christos 	{
   1451  1.1  christos 	  /* We must restore the print functions before trying to print the
   1452  1.1  christos 	     error message.  */
   1453  1.1  christos 	  info->fprintf_func = save_printer;
   1454  1.1  christos 	  info->print_address_func = save_print_address;
   1455  1.1  christos 	  info->fprintf_func (info->stream,
   1456  1.1  christos 			      /* xgettext:c-format */
   1457  1.1  christos 			      _("<internal error in opcode table: %s %s>\n"),
   1458  1.1  christos 			      best->name, best->args);
   1459  1.1  christos 	  return 2;
   1460  1.1  christos 	}
   1461  1.1  christos     }
   1462  1.1  christos 
   1463  1.1  christos   p = save_p;
   1464  1.1  christos   info->fprintf_func = save_printer;
   1465  1.1  christos   info->print_address_func = save_print_address;
   1466  1.1  christos 
   1467  1.1  christos   d = args;
   1468  1.1  christos 
   1469  1.1  christos   info->fprintf_func (info->stream, "%s", best->name);
   1470  1.1  christos 
   1471  1.1  christos   if (*d)
   1472  1.1  christos     info->fprintf_func (info->stream, " ");
   1473  1.1  christos 
   1474  1.1  christos   while (*d)
   1475  1.1  christos     {
   1476  1.1  christos       p += print_insn_arg (d, buffer, p, memaddr + (p - buffer), info);
   1477  1.1  christos       d += 2;
   1478  1.1  christos 
   1479  1.1  christos       if (*d && *(d - 2) != 'I' && *d != 'k')
   1480  1.1  christos 	info->fprintf_func (info->stream, ",");
   1481  1.1  christos     }
   1482  1.1  christos 
   1483  1.1  christos   return p - buffer;
   1484  1.1  christos }
   1485  1.1  christos 
   1486  1.1  christos /* Try to interpret the instruction at address MEMADDR as one that
   1487  1.7  christos    can execute on a processor with the features given by ARCH_MASK.
   1488  1.7  christos    If successful, print the instruction to INFO->STREAM and return
   1489  1.1  christos    its length in bytes.  Return 0 otherwise.  Return -1 on memory
   1490  1.1  christos    error.  */
   1491  1.1  christos 
   1492  1.1  christos static int
   1493  1.1  christos m68k_scan_mask (bfd_vma memaddr, disassemble_info *info,
   1494  1.1  christos 		unsigned int arch_mask)
   1495  1.1  christos {
   1496  1.1  christos   int i;
   1497  1.1  christos   const char *d;
   1498  1.1  christos   static const struct m68k_opcode **opcodes[16];
   1499  1.1  christos   static int numopcodes[16];
   1500  1.1  christos   int val;
   1501  1.1  christos   int major_opcode;
   1502  1.1  christos 
   1503  1.1  christos   struct private *priv = (struct private *) info->private_data;
   1504  1.1  christos   bfd_byte *buffer = priv->the_buffer;
   1505  1.1  christos 
   1506  1.1  christos   if (!opcodes[0])
   1507  1.1  christos     {
   1508  1.1  christos       /* Speed up the matching by sorting the opcode
   1509  1.1  christos 	 table on the upper four bits of the opcode.  */
   1510  1.1  christos       const struct m68k_opcode **opc_pointer[16];
   1511  1.1  christos 
   1512  1.1  christos       /* First count how many opcodes are in each of the sixteen buckets.  */
   1513  1.1  christos       for (i = 0; i < m68k_numopcodes; i++)
   1514  1.1  christos 	numopcodes[(m68k_opcodes[i].opcode >> 28) & 15]++;
   1515  1.1  christos 
   1516  1.1  christos       /* Then create a sorted table of pointers
   1517  1.1  christos 	 that point into the unsorted table.  */
   1518  1.1  christos       opc_pointer[0] = xmalloc (sizeof (struct m68k_opcode *)
   1519  1.1  christos 				* m68k_numopcodes);
   1520  1.1  christos       opcodes[0] = opc_pointer[0];
   1521  1.1  christos 
   1522  1.1  christos       for (i = 1; i < 16; i++)
   1523  1.1  christos 	{
   1524  1.1  christos 	  opc_pointer[i] = opc_pointer[i - 1] + numopcodes[i - 1];
   1525  1.1  christos 	  opcodes[i] = opc_pointer[i];
   1526  1.1  christos 	}
   1527  1.1  christos 
   1528  1.1  christos       for (i = 0; i < m68k_numopcodes; i++)
   1529  1.1  christos 	*opc_pointer[(m68k_opcodes[i].opcode >> 28) & 15]++ = &m68k_opcodes[i];
   1530  1.7  christos     }
   1531  1.7  christos 
   1532  1.1  christos   if (!FETCH_DATA (info, buffer + 2))
   1533  1.1  christos     return -1;
   1534  1.1  christos   major_opcode = (buffer[0] >> 4) & 15;
   1535  1.1  christos 
   1536  1.1  christos   for (i = 0; i < numopcodes[major_opcode]; i++)
   1537  1.1  christos     {
   1538  1.1  christos       const struct m68k_opcode *opc = opcodes[major_opcode][i];
   1539  1.1  christos       unsigned long opcode = opc->opcode;
   1540  1.1  christos       unsigned long match = opc->match;
   1541  1.1  christos       const char *args = opc->args;
   1542  1.1  christos 
   1543  1.1  christos       if (*args == '.')
   1544  1.1  christos 	args++;
   1545  1.1  christos 
   1546  1.1  christos       if (((0xff & buffer[0] & (match >> 24)) == (0xff & (opcode >> 24)))
   1547  1.1  christos 	  && ((0xff & buffer[1] & (match >> 16)) == (0xff & (opcode >> 16)))
   1548  1.1  christos 	  /* Only fetch the next two bytes if we need to.  */
   1549  1.1  christos 	  && (((0xffff & match) == 0)
   1550  1.1  christos 	      ||
   1551  1.1  christos 	      (FETCH_DATA (info, buffer + 4)
   1552  1.1  christos 	       && ((0xff & buffer[2] & (match >> 8)) == (0xff & (opcode >> 8)))
   1553  1.1  christos 	       && ((0xff & buffer[3] & match) == (0xff & opcode)))
   1554  1.1  christos 	      )
   1555  1.1  christos 	  && (opc->arch & arch_mask) != 0)
   1556  1.1  christos 	{
   1557  1.1  christos 	  /* Don't use for printout the variants of divul and divsl
   1558  1.1  christos 	     that have the same register number in two places.
   1559  1.1  christos 	     The more general variants will match instead.  */
   1560  1.1  christos 	  for (d = args; *d; d += 2)
   1561  1.1  christos 	    if (d[1] == 'D')
   1562  1.1  christos 	      break;
   1563  1.1  christos 
   1564  1.1  christos 	  /* Don't use for printout the variants of most floating
   1565  1.1  christos 	     point coprocessor instructions which use the same
   1566  1.1  christos 	     register number in two places, as above.  */
   1567  1.1  christos 	  if (*d == '\0')
   1568  1.1  christos 	    for (d = args; *d; d += 2)
   1569  1.1  christos 	      if (d[1] == 't')
   1570  1.1  christos 		break;
   1571  1.1  christos 
   1572  1.1  christos 	  /* Don't match fmovel with more than one register;
   1573  1.1  christos 	     wait for fmoveml.  */
   1574  1.1  christos 	  if (*d == '\0')
   1575  1.1  christos 	    {
   1576  1.1  christos 	      for (d = args; *d; d += 2)
   1577  1.1  christos 		{
   1578  1.1  christos 		  if (d[0] == 's' && d[1] == '8')
   1579  1.1  christos 		    {
   1580  1.1  christos 		      val = fetch_arg (buffer, d[1], 3, info);
   1581  1.1  christos 		      if (val < 0)
   1582  1.1  christos 			return 0;
   1583  1.1  christos 		      if ((val & (val - 1)) != 0)
   1584  1.1  christos 			break;
   1585  1.1  christos 		    }
   1586  1.1  christos 		}
   1587  1.1  christos 	    }
   1588  1.1  christos 
   1589  1.1  christos 	  /* Don't match FPU insns with non-default coprocessor ID.  */
   1590  1.1  christos 	  if (*d == '\0')
   1591  1.1  christos 	    {
   1592  1.1  christos 	      for (d = args; *d; d += 2)
   1593  1.1  christos 		{
   1594  1.1  christos 		  if (d[0] == 'I')
   1595  1.1  christos 		    {
   1596  1.1  christos 		      val = fetch_arg (buffer, 'd', 3, info);
   1597  1.1  christos 		      if (val != 1)
   1598  1.1  christos 			break;
   1599  1.1  christos 		    }
   1600  1.1  christos 		}
   1601  1.1  christos 	    }
   1602  1.1  christos 
   1603  1.1  christos 	  if (*d == '\0')
   1604  1.1  christos 	    if ((val = match_insn_m68k (memaddr, info, opc)))
   1605  1.1  christos 	      return val;
   1606  1.1  christos 	}
   1607  1.6  christos     }
   1608  1.1  christos   return 0;
   1609  1.1  christos }
   1610  1.1  christos 
   1611  1.1  christos /* Print the m68k instruction at address MEMADDR in debugged memory,
   1612  1.1  christos    on INFO->STREAM.  Returns length of the instruction, in bytes.  */
   1613  1.1  christos 
   1614  1.1  christos int
   1615  1.1  christos print_insn_m68k (bfd_vma memaddr, disassemble_info *info)
   1616  1.1  christos {
   1617  1.1  christos   unsigned int arch_mask;
   1618  1.1  christos   struct private priv;
   1619  1.1  christos   int val;
   1620  1.1  christos 
   1621  1.1  christos   bfd_byte *buffer = priv.the_buffer;
   1622  1.1  christos 
   1623  1.1  christos   info->private_data = & priv;
   1624  1.1  christos   /* Tell objdump to use two bytes per chunk
   1625  1.1  christos      and six bytes per line for displaying raw data.  */
   1626  1.1  christos   info->bytes_per_chunk = 2;
   1627  1.1  christos   info->bytes_per_line = 6;
   1628  1.1  christos   info->display_endian = BFD_ENDIAN_BIG;
   1629  1.1  christos   priv.max_fetched = priv.the_buffer;
   1630  1.1  christos   priv.insn_start = memaddr;
   1631  1.1  christos 
   1632  1.1  christos   arch_mask = bfd_m68k_mach_to_features (info->mach);
   1633  1.1  christos   if (!arch_mask)
   1634  1.1  christos     {
   1635  1.1  christos       /* First try printing an m680x0 instruction.  Try printing a Coldfire
   1636  1.7  christos 	 one if that fails.  */
   1637  1.1  christos       val = m68k_scan_mask (memaddr, info, m68k_mask);
   1638  1.1  christos       if (val <= 0)
   1639  1.1  christos 	val = m68k_scan_mask (memaddr, info, mcf_mask);
   1640  1.1  christos     }
   1641  1.1  christos   else
   1642  1.1  christos     {
   1643  1.1  christos       val = m68k_scan_mask (memaddr, info, arch_mask);
   1644  1.1  christos     }
   1645  1.1  christos 
   1646  1.1  christos   if (val == 0)
   1647  1.1  christos     /* Handle undefined instructions.  */
   1648  1.1  christos     info->fprintf_func (info->stream, ".short 0x%04x", (buffer[0] << 8) + buffer[1]);
   1649  1.1  christos 
   1650                  return val ? val : 2;
   1651                }
   1652