Home | History | Annotate | Line # | Download | only in opcodes
ns32k-dis.c revision 1.1.1.5
      1 /* Print National Semiconductor 32000 instructions.
      2    Copyright (C) 1986-2018 Free Software Foundation, Inc.
      3 
      4    This file is part of the GNU opcodes library.
      5 
      6    This library is free software; you can redistribute it and/or modify
      7    it under the terms of the GNU General Public License as published by
      8    the Free Software Foundation; either version 3, or (at your option)
      9    any later version.
     10 
     11    It is distributed in the hope that it will be useful, but WITHOUT
     12    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     13    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     14    License for more details.
     15 
     16    You should have received a copy of the GNU General Public License
     17    along with this program; if not, write to the Free Software
     18    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     19    MA 02110-1301, USA.  */
     20 
     21 #include "sysdep.h"
     22 #include "bfd.h"
     23 #include "disassemble.h"
     24 #if !defined(const) && !defined(__STDC__)
     25 #define const
     26 #endif
     27 #include "opcode/ns32k.h"
     28 #include "opintl.h"
     29 
     30 static disassemble_info *dis_info;
     31 
     32 /* Hacks to get it to compile <= READ THESE AS FIXES NEEDED.  */
     33 #define INVALID_FLOAT(val, size) invalid_float ((bfd_byte *) val, size)
     34 
     35 static long
     36 read_memory_integer (unsigned char * addr, int nr)
     37 {
     38   long val;
     39   int i;
     40 
     41   for (val = 0, i = nr - 1; i >= 0; i--)
     42     {
     43       val =  (val << 8);
     44       val |= (0xff & *(addr + i));
     45     }
     46   return val;
     47 }
     48 
     49 /* 32000 instructions are never longer than this.  */
     50 #define MAXLEN 62
     51 
     52 #include <setjmp.h>
     53 
     54 struct private
     55 {
     56   /* Points to first byte not fetched.  */
     57   bfd_byte *max_fetched;
     58   bfd_byte the_buffer[MAXLEN];
     59   bfd_vma insn_start;
     60   OPCODES_SIGJMP_BUF bailout;
     61 };
     62 
     63 
     64 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
     65    to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
     66    on error.  */
     67 #define FETCH_DATA(info, addr) \
     68   ((addr) <= ((struct private *)(info->private_data))->max_fetched \
     69    ? 1 : fetch_data ((info), (addr)))
     70 
     71 static int
     72 fetch_data (struct disassemble_info *info, bfd_byte *addr)
     73 {
     74   int status;
     75   struct private *priv = (struct private *) info->private_data;
     76   bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
     77 
     78   status = (*info->read_memory_func) (start,
     79 				      priv->max_fetched,
     80 				      addr - priv->max_fetched,
     81 				      info);
     82   if (status != 0)
     83     {
     84       (*info->memory_error_func) (status, start, info);
     85       OPCODES_SIGLONGJMP (priv->bailout, 1);
     86     }
     87   else
     88     priv->max_fetched = addr;
     89   return 1;
     90 }
     91 
     92 /* Number of elements in the opcode table.  */
     93 #define NOPCODES (sizeof ns32k_opcodes / sizeof ns32k_opcodes[0])
     94 
     95 #define NEXT_IS_ADDR	'|'
     96 
     97 
     98 struct ns32k_option
    100 {
    101   char *pattern;		/* The option itself.  */
    102   unsigned long value;		/* Binary value of the option.  */
    103   unsigned long match;		/* These bits must match.  */
    104 };
    105 
    106 
    107 static const struct ns32k_option opt_u[]= /* Restore, exit.  */
    109 {
    110   { "r0",	0x80,	0x80	},
    111   { "r1",	0x40,	0x40	},
    112   { "r2",	0x20,	0x20	},
    113   { "r3",	0x10,	0x10	},
    114   { "r4",	0x08,	0x08	},
    115   { "r5",	0x04,	0x04	},
    116   { "r6",	0x02,	0x02	},
    117   { "r7",	0x01,	0x01	},
    118   {  0 ,	0x00,	0x00	}
    119 };
    120 
    121 static const struct ns32k_option opt_U[]= /* Save, enter.  */
    122 {
    123   { "r0",	0x01,	0x01	},
    124   { "r1",	0x02,	0x02	},
    125   { "r2",	0x04,	0x04	},
    126   { "r3",	0x08,	0x08	},
    127   { "r4",	0x10,	0x10	},
    128   { "r5",	0x20,	0x20	},
    129   { "r6",	0x40,	0x40	},
    130   { "r7",	0x80,	0x80	},
    131   {  0 ,	0x00,	0x00	}
    132 };
    133 
    134 static const struct ns32k_option opt_O[]= /* Setcfg.  */
    135 {
    136   { "c",	0x8,	0x8	},
    137   { "m",	0x4,	0x4	},
    138   { "f",	0x2,	0x2	},
    139   { "i",	0x1,	0x1	},
    140   {  0 ,	0x0,	0x0	}
    141 };
    142 
    143 static const struct ns32k_option opt_C[]= /* Cinv.  */
    144 {
    145   { "a",	0x4,	0x4	},
    146   { "i",	0x2,	0x2	},
    147   { "d",	0x1,	0x1	},
    148   {  0 ,	0x0,	0x0	}
    149 };
    150 
    151 static const struct ns32k_option opt_S[]= /* String inst.  */
    152 {
    153   { "b",	0x1,	0x1	},
    154   { "u",	0x6,	0x6	},
    155   { "w",	0x2,	0x2	},
    156   {  0 ,	0x0,	0x0	}
    157 };
    158 
    159 static const struct ns32k_option list_P532[]= /* Lpr spr.  */
    160 {
    161   { "us",	0x0,	0xf	},
    162   { "dcr",	0x1,	0xf	},
    163   { "bpc",	0x2,	0xf	},
    164   { "dsr",	0x3,	0xf	},
    165   { "car",	0x4,	0xf	},
    166   { "fp",	0x8,	0xf	},
    167   { "sp",	0x9,	0xf	},
    168   { "sb",	0xa,	0xf	},
    169   { "usp",	0xb,	0xf	},
    170   { "cfg",	0xc,	0xf	},
    171   { "psr",	0xd,	0xf	},
    172   { "intbase",	0xe,	0xf	},
    173   { "mod",	0xf,	0xf	},
    174   {  0 ,	0x00,	0xf	}
    175 };
    176 
    177 static const struct ns32k_option list_M532[]= /* Lmr smr.  */
    178 {
    179   { "mcr",	0x9,	0xf	},
    180   { "msr",	0xa,	0xf	},
    181   { "tear",	0xb,	0xf	},
    182   { "ptb0",	0xc,	0xf	},
    183   { "ptb1",	0xd,	0xf	},
    184   { "ivar0",	0xe,	0xf	},
    185   { "ivar1",	0xf,	0xf	},
    186   {  0 ,	0x0,	0xf	}
    187 };
    188 
    189 static const struct ns32k_option list_P032[]= /* Lpr spr.  */
    190 {
    191   { "upsr",	0x0,	0xf	},
    192   { "fp",	0x8,	0xf	},
    193   { "sp",	0x9,	0xf	},
    194   { "sb",	0xa,	0xf	},
    195   { "psr",	0xb,	0xf	},
    196   { "intbase",	0xe,	0xf	},
    197   { "mod",	0xf,	0xf	},
    198   {  0 ,	0x0,	0xf	}
    199 };
    200 
    201 static const struct ns32k_option list_M032[]= /* Lmr smr.  */
    202 {
    203   { "bpr0",	0x0,	0xf	},
    204   { "bpr1",	0x1,	0xf	},
    205   { "pf0",	0x4,	0xf	},
    206   { "pf1",	0x5,	0xf	},
    207   { "sc",	0x8,	0xf	},
    208   { "msr",	0xa,	0xf	},
    209   { "bcnt",	0xb,	0xf	},
    210   { "ptb0",	0xc,	0xf	},
    211   { "ptb1",	0xd,	0xf	},
    212   { "eia",	0xf,	0xf	},
    213   {  0 ,	0x0,	0xf	}
    214 };
    215 
    216 
    217 /* Figure out which options are present.   */
    218 
    219 static void
    220 optlist (int options, const struct ns32k_option * optionP, char * result)
    221 {
    222   if (options == 0)
    223     {
    224       sprintf (result, "[]");
    225       return;
    226     }
    227 
    228   sprintf (result, "[");
    229 
    230   for (; (options != 0) && optionP->pattern; optionP++)
    231     {
    232       if ((options & optionP->match) == optionP->value)
    233 	{
    234 	  /* We found a match, update result and options.  */
    235 	  strcat (result, optionP->pattern);
    236 	  options &= ~optionP->value;
    237 	  if (options != 0)	/* More options to come.  */
    238 	    strcat (result, ",");
    239 	}
    240     }
    241 
    242   if (options != 0)
    243     strcat (result, "undefined");
    244 
    245   strcat (result, "]");
    246 }
    247 
    248 static void
    249 list_search (int reg_value, const struct ns32k_option *optionP, char *result)
    250 {
    251   for (; optionP->pattern; optionP++)
    252     {
    253       if ((reg_value & optionP->match) == optionP->value)
    254 	{
    255 	  sprintf (result, "%s", optionP->pattern);
    256 	  return;
    257 	}
    258     }
    259   sprintf (result, "undefined");
    260 }
    261 
    262 /* Extract "count" bits starting "offset" bits into buffer.  */
    264 
    265 static int
    266 bit_extract (bfd_byte *buffer, int offset, int count)
    267 {
    268   int result;
    269   int bit;
    270 
    271   buffer += offset >> 3;
    272   offset &= 7;
    273   bit = 1;
    274   result = 0;
    275   while (count--)
    276     {
    277       FETCH_DATA (dis_info, buffer + 1);
    278       if ((*buffer & (1 << offset)))
    279 	result |= bit;
    280       if (++offset == 8)
    281 	{
    282 	  offset = 0;
    283 	  buffer++;
    284 	}
    285       bit <<= 1;
    286     }
    287   return result;
    288 }
    289 
    290 /* Like bit extract but the buffer is valid and doen't need to be fetched.  */
    291 
    292 static int
    293 bit_extract_simple (bfd_byte *buffer, int offset, int count)
    294 {
    295   int result;
    296   int bit;
    297 
    298   buffer += offset >> 3;
    299   offset &= 7;
    300   bit = 1;
    301   result = 0;
    302   while (count--)
    303     {
    304       if ((*buffer & (1 << offset)))
    305 	result |= bit;
    306       if (++offset == 8)
    307 	{
    308 	  offset = 0;
    309 	  buffer++;
    310 	}
    311       bit <<= 1;
    312     }
    313   return result;
    314 }
    315 
    316 static void
    317 bit_copy (bfd_byte *buffer, int offset, int count, char *to)
    318 {
    319   for (; count > 8; count -= 8, to++, offset += 8)
    320     *to = bit_extract (buffer, offset, 8);
    321   *to = bit_extract (buffer, offset, count);
    322 }
    323 
    324 static int
    325 sign_extend (int value, int bits)
    326 {
    327   value = value & ((1 << bits) - 1);
    328   return (value & (1 << (bits - 1))
    329 	  ? value | (~((1 << bits) - 1))
    330 	  : value);
    331 }
    332 
    333 static void
    334 flip_bytes (char *ptr, int count)
    335 {
    336   char tmp;
    337 
    338   while (count > 0)
    339     {
    340       tmp = ptr[0];
    341       ptr[0] = ptr[count - 1];
    342       ptr[count - 1] = tmp;
    343       ptr++;
    344       count -= 2;
    345     }
    346 }
    347 
    348 /* Given a character C, does it represent a general addressing mode?  */
    350 #define Is_gen(c) \
    351   ((c) == 'F' || (c) == 'L' || (c) == 'B' \
    352    || (c) == 'W' || (c) == 'D' || (c) == 'A' || (c) == 'I' || (c) == 'Z')
    353 
    354 /* Adressing modes.  */
    355 #define Adrmod_index_byte        0x1c
    356 #define Adrmod_index_word        0x1d
    357 #define Adrmod_index_doubleword  0x1e
    358 #define Adrmod_index_quadword    0x1f
    359 
    360 /* Is MODE an indexed addressing mode?  */
    361 #define Adrmod_is_index(mode) \
    362   (   mode == Adrmod_index_byte \
    363    || mode == Adrmod_index_word \
    364    || mode == Adrmod_index_doubleword \
    365    || mode == Adrmod_index_quadword)
    366 
    367 
    368 static int
    370 get_displacement (bfd_byte *buffer, int *aoffsetp)
    371 {
    372   int Ivalue;
    373   short Ivalue2;
    374 
    375   Ivalue = bit_extract (buffer, *aoffsetp, 8);
    376   switch (Ivalue & 0xc0)
    377     {
    378     case 0x00:
    379     case 0x40:
    380       Ivalue = sign_extend (Ivalue, 7);
    381       *aoffsetp += 8;
    382       break;
    383     case 0x80:
    384       Ivalue2 = bit_extract (buffer, *aoffsetp, 16);
    385       flip_bytes ((char *) & Ivalue2, 2);
    386       Ivalue = sign_extend (Ivalue2, 14);
    387       *aoffsetp += 16;
    388       break;
    389     case 0xc0:
    390       Ivalue = bit_extract (buffer, *aoffsetp, 32);
    391       flip_bytes ((char *) & Ivalue, 4);
    392       Ivalue = sign_extend (Ivalue, 30);
    393       *aoffsetp += 32;
    394       break;
    395     }
    396   return Ivalue;
    397 }
    398 
    399 #if 1 /* A version that should work on ns32k f's&d's on any machine.  */
    400 static int
    401 invalid_float (bfd_byte *p, int len)
    402 {
    403   int val;
    404 
    405   if (len == 4)
    406     val = (bit_extract_simple (p, 23, 8)/*exponent*/ == 0xff
    407 	   || (bit_extract_simple (p, 23, 8)/*exponent*/ == 0
    408 	       && bit_extract_simple (p, 0, 23)/*mantisa*/ != 0));
    409   else if (len == 8)
    410     val = (bit_extract_simple (p, 52, 11)/*exponent*/ == 0x7ff
    411 	   || (bit_extract_simple (p, 52, 11)/*exponent*/ == 0
    412 	       && (bit_extract_simple (p, 0, 32)/*low mantisa*/ != 0
    413 		   || bit_extract_simple (p, 32, 20)/*high mantisa*/ != 0)));
    414   else
    415     val = 1;
    416   return (val);
    417 }
    418 #else
    419 /* Assumes the bytes have been swapped to local order.  */
    420 typedef union
    421 {
    422   double d;
    423   float f;
    424   struct { unsigned m:23, e:8, :1;} sf;
    425   struct { unsigned lm; unsigned m:20, e:11, :1;} sd;
    426 } float_type_u;
    427 
    428 static int
    429 invalid_float (float_type_u *p, int len)
    430 {
    431   int val;
    432 
    433   if (len == sizeof (float))
    434     val = (p->sf.e == 0xff
    435 	   || (p->sf.e == 0 && p->sf.m != 0));
    436   else if (len == sizeof (double))
    437     val = (p->sd.e == 0x7ff
    438 	   || (p->sd.e == 0 && (p->sd.m != 0 || p->sd.lm != 0)));
    439   else
    440     val = 1;
    441   return val;
    442 }
    443 #endif
    444 
    445 /* Print an instruction operand of category given by d.  IOFFSET is
    446    the bit position below which small (<1 byte) parts of the operand can
    447    be found (usually in the basic instruction, but for indexed
    448    addressing it can be in the index byte).  AOFFSETP is a pointer to the
    449    bit position of the addressing extension.  BUFFER contains the
    450    instruction.  ADDR is where BUFFER was read from.  Put the disassembled
    451    version of the operand in RESULT.  INDEX_OFFSET is the bit position
    452    of the index byte (it contains garbage if this operand is not a
    453    general operand using scaled indexed addressing mode).  */
    454 
    455 static int
    456 print_insn_arg (int d,
    457 		int ioffset,
    458 		int *aoffsetp,
    459 		bfd_byte *buffer,
    460 		bfd_vma addr,
    461 		char *result,
    462 		int index_offset)
    463 {
    464   union
    465   {
    466     float f;
    467     double d;
    468     int i[2];
    469   } value;
    470   int Ivalue;
    471   int addr_mode;
    472   int disp1, disp2;
    473   int size;
    474 
    475   switch (d)
    476     {
    477     case 'f':
    478       /* A "gen" operand but 5 bits from the end of instruction.  */
    479       ioffset -= 5;
    480       /* Fall through.  */
    481     case 'Z':
    482     case 'F':
    483     case 'L':
    484     case 'I':
    485     case 'B':
    486     case 'W':
    487     case 'D':
    488     case 'A':
    489       addr_mode = bit_extract (buffer, ioffset - 5, 5);
    490       ioffset -= 5;
    491       switch (addr_mode)
    492 	{
    493 	case 0x0: case 0x1: case 0x2: case 0x3:
    494 	case 0x4: case 0x5: case 0x6: case 0x7:
    495 	  /* Register mode R0 -- R7.  */
    496 	  switch (d)
    497 	    {
    498 	    case 'F':
    499 	    case 'L':
    500 	    case 'Z':
    501 	      sprintf (result, "f%d", addr_mode);
    502 	      break;
    503 	    default:
    504 	      sprintf (result, "r%d", addr_mode);
    505 	    }
    506 	  break;
    507 	case 0x8: case 0x9: case 0xa: case 0xb:
    508 	case 0xc: case 0xd: case 0xe: case 0xf:
    509 	  /* Register relative disp(R0 -- R7).  */
    510 	  disp1 = get_displacement (buffer, aoffsetp);
    511 	  sprintf (result, "%d(r%d)", disp1, addr_mode & 7);
    512 	  break;
    513 	case 0x10:
    514 	case 0x11:
    515 	case 0x12:
    516 	  /* Memory relative disp2(disp1(FP, SP, SB)).  */
    517 	  disp1 = get_displacement (buffer, aoffsetp);
    518 	  disp2 = get_displacement (buffer, aoffsetp);
    519 	  sprintf (result, "%d(%d(%s))", disp2, disp1,
    520 		   addr_mode == 0x10 ? "fp" : addr_mode == 0x11 ? "sp" : "sb");
    521 	  break;
    522 	case 0x13:
    523 	  /* Reserved.  */
    524 	  sprintf (result, "reserved");
    525 	  break;
    526 	case 0x14:
    527 	  /* Immediate.  */
    528 	  switch (d)
    529 	    {
    530 	    case 'I':
    531 	    case 'Z':
    532 	    case 'A':
    533 	      /* I and Z are output operands and can`t be immediate
    534 	         A is an address and we can`t have the address of
    535 	         an immediate either. We don't know how much to increase
    536 	         aoffsetp by since whatever generated this is broken
    537 	         anyway!  */
    538 	      sprintf (result, _("$<undefined>"));
    539 	      break;
    540 	    case 'B':
    541 	      Ivalue = bit_extract (buffer, *aoffsetp, 8);
    542 	      Ivalue = sign_extend (Ivalue, 8);
    543 	      *aoffsetp += 8;
    544 	      sprintf (result, "$%d", Ivalue);
    545 	      break;
    546 	    case 'W':
    547 	      Ivalue = bit_extract (buffer, *aoffsetp, 16);
    548 	      flip_bytes ((char *) & Ivalue, 2);
    549 	      *aoffsetp += 16;
    550 	      Ivalue = sign_extend (Ivalue, 16);
    551 	      sprintf (result, "$%d", Ivalue);
    552 	      break;
    553 	    case 'D':
    554 	      Ivalue = bit_extract (buffer, *aoffsetp, 32);
    555 	      flip_bytes ((char *) & Ivalue, 4);
    556 	      *aoffsetp += 32;
    557 	      sprintf (result, "$%d", Ivalue);
    558 	      break;
    559 	    case 'F':
    560 	      bit_copy (buffer, *aoffsetp, 32, (char *) &value.f);
    561 	      flip_bytes ((char *) &value.f, 4);
    562 	      *aoffsetp += 32;
    563 	      if (INVALID_FLOAT (&value.f, 4))
    564 		sprintf (result, "<<invalid float 0x%.8x>>", value.i[0]);
    565 	      else /* Assume host has ieee float.  */
    566 		sprintf (result, "$%g", value.f);
    567 	      break;
    568 	    case 'L':
    569 	      bit_copy (buffer, *aoffsetp, 64, (char *) &value.d);
    570 	      flip_bytes ((char *) &value.d, 8);
    571 	      *aoffsetp += 64;
    572 	      if (INVALID_FLOAT (&value.d, 8))
    573 		sprintf (result, "<<invalid double 0x%.8x%.8x>>",
    574 			 value.i[1], value.i[0]);
    575 	      else /* Assume host has ieee float.  */
    576 		sprintf (result, "$%g", value.d);
    577 	      break;
    578 	    }
    579 	  break;
    580 	case 0x15:
    581 	  /* Absolute @disp.  */
    582 	  disp1 = get_displacement (buffer, aoffsetp);
    583 	  sprintf (result, "@|%d|", disp1);
    584 	  break;
    585 	case 0x16:
    586 	  /* External EXT(disp1) + disp2 (Mod table stuff).  */
    587 	  disp1 = get_displacement (buffer, aoffsetp);
    588 	  disp2 = get_displacement (buffer, aoffsetp);
    589 	  sprintf (result, "EXT(%d) + %d", disp1, disp2);
    590 	  break;
    591 	case 0x17:
    592 	  /* Top of stack tos.  */
    593 	  sprintf (result, "tos");
    594 	  break;
    595 	case 0x18:
    596 	  /* Memory space disp(FP).  */
    597 	  disp1 = get_displacement (buffer, aoffsetp);
    598 	  sprintf (result, "%d(fp)", disp1);
    599 	  break;
    600 	case 0x19:
    601 	  /* Memory space disp(SP).  */
    602 	  disp1 = get_displacement (buffer, aoffsetp);
    603 	  sprintf (result, "%d(sp)", disp1);
    604 	  break;
    605 	case 0x1a:
    606 	  /* Memory space disp(SB).  */
    607 	  disp1 = get_displacement (buffer, aoffsetp);
    608 	  sprintf (result, "%d(sb)", disp1);
    609 	  break;
    610 	case 0x1b:
    611 	  /* Memory space disp(PC).  */
    612 	  disp1 = get_displacement (buffer, aoffsetp);
    613 	  *result++ = NEXT_IS_ADDR;
    614 	  sprintf_vma (result, addr + disp1);
    615 	  result += strlen (result);
    616 	  *result++ = NEXT_IS_ADDR;
    617 	  *result = '\0';
    618 	  break;
    619 	case 0x1c:
    620 	case 0x1d:
    621 	case 0x1e:
    622 	case 0x1f:
    623 	  {
    624 	    int bit_index;
    625 	    static const char *ind = "bwdq";
    626 	    char *off;
    627 
    628 	    /* Scaled index basemode[R0 -- R7:B,W,D,Q].  */
    629 	    bit_index = bit_extract (buffer, index_offset - 8, 3);
    630 	    print_insn_arg (d, index_offset, aoffsetp, buffer, addr,
    631 			    result, 0);
    632 	    off = result + strlen (result);
    633 	    sprintf (off, "[r%d:%c]", bit_index, ind[addr_mode & 3]);
    634 	  }
    635 	  break;
    636 	}
    637       break;
    638     case 'H':
    639     case 'q':
    640       Ivalue = bit_extract (buffer, ioffset-4, 4);
    641       Ivalue = sign_extend (Ivalue, 4);
    642       sprintf (result, "%d", Ivalue);
    643       ioffset -= 4;
    644       break;
    645     case 'r':
    646       Ivalue = bit_extract (buffer, ioffset-3, 3);
    647       sprintf (result, "r%d", Ivalue&7);
    648       ioffset -= 3;
    649       break;
    650     case 'd':
    651       sprintf (result, "%d", get_displacement (buffer, aoffsetp));
    652       break;
    653     case 'b':
    654       Ivalue = get_displacement (buffer, aoffsetp);
    655       /* Warning!!  HACK ALERT!
    656          Operand type 'b' is only used by the cmp{b,w,d} and
    657          movm{b,w,d} instructions; we need to know whether
    658          it's a `b' or `w' or `d' instruction; and for both
    659          cmpm and movm it's stored at the same place so we
    660          just grab two bits of the opcode and look at it...  */
    661       size = bit_extract(buffer, ioffset-6, 2);
    662       if (size == 0)		/* 00 => b.  */
    663 	size = 1;
    664       else if (size == 1)	/* 01 => w.  */
    665 	size = 2;
    666       else
    667 	size = 4;		/* 11 => d.  */
    668 
    669       sprintf (result, "%d", (Ivalue / size) + 1);
    670       break;
    671     case 'p':
    672       *result++ = NEXT_IS_ADDR;
    673       sprintf_vma (result, addr + get_displacement (buffer, aoffsetp));
    674       result += strlen (result);
    675       *result++ = NEXT_IS_ADDR;
    676       *result = '\0';
    677       break;
    678     case 'i':
    679       Ivalue = bit_extract (buffer, *aoffsetp, 8);
    680       *aoffsetp += 8;
    681       sprintf (result, "0x%x", Ivalue);
    682       break;
    683     case 'u':
    684       Ivalue = bit_extract (buffer, *aoffsetp, 8);
    685       optlist (Ivalue, opt_u, result);
    686       *aoffsetp += 8;
    687       break;
    688     case 'U':
    689       Ivalue = bit_extract (buffer, *aoffsetp, 8);
    690       optlist (Ivalue, opt_U, result);
    691       *aoffsetp += 8;
    692       break;
    693     case 'O':
    694       Ivalue = bit_extract (buffer, ioffset - 9, 9);
    695       optlist (Ivalue, opt_O, result);
    696       ioffset -= 9;
    697       break;
    698     case 'C':
    699       Ivalue = bit_extract (buffer, ioffset - 4, 4);
    700       optlist (Ivalue, opt_C, result);
    701       ioffset -= 4;
    702       break;
    703     case 'S':
    704       Ivalue = bit_extract (buffer, ioffset - 8, 8);
    705       optlist (Ivalue, opt_S, result);
    706       ioffset -= 8;
    707       break;
    708     case 'M':
    709       Ivalue = bit_extract (buffer, ioffset - 4, 4);
    710       list_search (Ivalue, 0 ? list_M032 : list_M532, result);
    711       ioffset -= 4;
    712       break;
    713     case 'P':
    714       Ivalue = bit_extract (buffer, ioffset - 4, 4);
    715       list_search (Ivalue, 0 ? list_P032 : list_P532, result);
    716       ioffset -= 4;
    717       break;
    718     case 'g':
    719       Ivalue = bit_extract (buffer, *aoffsetp, 3);
    720       sprintf (result, "%d", Ivalue);
    721       *aoffsetp += 3;
    722       break;
    723     case 'G':
    724       Ivalue = bit_extract(buffer, *aoffsetp, 5);
    725       sprintf (result, "%d", Ivalue + 1);
    726       *aoffsetp += 5;
    727       break;
    728     }
    729   return ioffset;
    730 }
    731 
    732 
    733 /* Print the 32000 instruction at address MEMADDR in debugged memory,
    735    on STREAM.  Returns length of the instruction, in bytes.  */
    736 
    737 int
    738 print_insn_ns32k (bfd_vma memaddr, disassemble_info *info)
    739 {
    740   unsigned int i;
    741   const char *d;
    742   unsigned short first_word;
    743   int ioffset;		/* Bits into instruction.  */
    744   int aoffset;		/* Bits into arguments.  */
    745   char arg_bufs[MAX_ARGS+1][ARG_LEN];
    746   int argnum;
    747   int maxarg;
    748   struct private priv;
    749   bfd_byte *buffer = priv.the_buffer;
    750   dis_info = info;
    751 
    752   info->private_data = & priv;
    753   priv.max_fetched = priv.the_buffer;
    754   priv.insn_start = memaddr;
    755   if (OPCODES_SIGSETJMP (priv.bailout) != 0)
    756     /* Error return.  */
    757     return -1;
    758 
    759   /* Look for 8bit opcodes first. Other wise, fetching two bytes could take
    760      us over the end of accessible data unnecessarilly.  */
    761   FETCH_DATA (info, buffer + 1);
    762   for (i = 0; i < NOPCODES; i++)
    763     if (ns32k_opcodes[i].opcode_id_size <= 8
    764 	&& ((buffer[0]
    765 	     & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
    766 	    == ns32k_opcodes[i].opcode_seed))
    767       break;
    768   if (i == NOPCODES)
    769     {
    770       /* Maybe it is 9 to 16 bits big.  */
    771       FETCH_DATA (info, buffer + 2);
    772       first_word = read_memory_integer(buffer, 2);
    773 
    774       for (i = 0; i < NOPCODES; i++)
    775 	if ((first_word
    776 	     & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
    777 	    == ns32k_opcodes[i].opcode_seed)
    778 	  break;
    779 
    780       /* Handle undefined instructions.  */
    781       if (i == NOPCODES)
    782 	{
    783 	  (*dis_info->fprintf_func)(dis_info->stream, "0%o", buffer[0]);
    784 	  return 1;
    785 	}
    786     }
    787 
    788   (*dis_info->fprintf_func)(dis_info->stream, "%s", ns32k_opcodes[i].name);
    789 
    790   ioffset = ns32k_opcodes[i].opcode_size;
    791   aoffset = ns32k_opcodes[i].opcode_size;
    792   d = ns32k_opcodes[i].operands;
    793 
    794   if (*d)
    795     {
    796       /* Offset in bits of the first thing beyond each index byte.
    797 	 Element 0 is for operand A and element 1 is for operand B.
    798 	 The rest are irrelevant, but we put them here so we don't
    799 	 index outside the array.  */
    800       int index_offset[MAX_ARGS];
    801 
    802       /* 0 for operand A, 1 for operand B, greater for other args.  */
    803       int whicharg = 0;
    804 
    805       (*dis_info->fprintf_func)(dis_info->stream, "\t");
    806 
    807       maxarg = 0;
    808 
    809       /* First we have to find and keep track of the index bytes,
    810 	 if we are using scaled indexed addressing mode, since the index
    811 	 bytes occur right after the basic instruction, not as part
    812 	 of the addressing extension.  */
    813       if (Is_gen(d[1]))
    814 	{
    815 	  int addr_mode = bit_extract (buffer, ioffset - 5, 5);
    816 
    817 	  if (Adrmod_is_index (addr_mode))
    818 	    {
    819 	      aoffset += 8;
    820 	      index_offset[0] = aoffset;
    821 	    }
    822 	}
    823 
    824       if (d[2] && Is_gen(d[3]))
    825 	{
    826 	  int addr_mode = bit_extract (buffer, ioffset - 10, 5);
    827 
    828 	  if (Adrmod_is_index (addr_mode))
    829 	    {
    830 	      aoffset += 8;
    831 	      index_offset[1] = aoffset;
    832 	    }
    833 	}
    834 
    835       while (*d)
    836 	{
    837 	  argnum = *d - '1';
    838 	  d++;
    839 	  if (argnum > maxarg && argnum < MAX_ARGS)
    840 	    maxarg = argnum;
    841 	  ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer,
    842 				    memaddr, arg_bufs[argnum],
    843 				    index_offset[whicharg]);
    844 	  d++;
    845 	  whicharg++;
    846 	}
    847       for (argnum = 0; argnum <= maxarg; argnum++)
    848 	{
    849 	  bfd_vma addr;
    850 	  char *ch;
    851 
    852 	  for (ch = arg_bufs[argnum]; *ch;)
    853 	    {
    854 	      if (*ch == NEXT_IS_ADDR)
    855 		{
    856 		  ++ch;
    857 		  addr = bfd_scan_vma (ch, NULL, 16);
    858 		  (*dis_info->print_address_func) (addr, dis_info);
    859 		  while (*ch && *ch != NEXT_IS_ADDR)
    860 		    ++ch;
    861 		  if (*ch)
    862 		    ++ch;
    863 		}
    864 	      else
    865 		(*dis_info->fprintf_func)(dis_info->stream, "%c", *ch++);
    866 	    }
    867 	  if (argnum < maxarg)
    868 	    (*dis_info->fprintf_func)(dis_info->stream, ", ");
    869 	}
    870     }
    871   return aoffset / 8;
    872 }
    873