Home | History | Annotate | Download | only in opcodes
      1 /* Print National Semiconductor 32000 instructions.
      2    Copyright (C) 1986-2016 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 "dis-asm.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     case 'Z':
    481     case 'F':
    482     case 'L':
    483     case 'I':
    484     case 'B':
    485     case 'W':
    486     case 'D':
    487     case 'A':
    488       addr_mode = bit_extract (buffer, ioffset - 5, 5);
    489       ioffset -= 5;
    490       switch (addr_mode)
    491 	{
    492 	case 0x0: case 0x1: case 0x2: case 0x3:
    493 	case 0x4: case 0x5: case 0x6: case 0x7:
    494 	  /* Register mode R0 -- R7.  */
    495 	  switch (d)
    496 	    {
    497 	    case 'F':
    498 	    case 'L':
    499 	    case 'Z':
    500 	      sprintf (result, "f%d", addr_mode);
    501 	      break;
    502 	    default:
    503 	      sprintf (result, "r%d", addr_mode);
    504 	    }
    505 	  break;
    506 	case 0x8: case 0x9: case 0xa: case 0xb:
    507 	case 0xc: case 0xd: case 0xe: case 0xf:
    508 	  /* Register relative disp(R0 -- R7).  */
    509 	  disp1 = get_displacement (buffer, aoffsetp);
    510 	  sprintf (result, "%d(r%d)", disp1, addr_mode & 7);
    511 	  break;
    512 	case 0x10:
    513 	case 0x11:
    514 	case 0x12:
    515 	  /* Memory relative disp2(disp1(FP, SP, SB)).  */
    516 	  disp1 = get_displacement (buffer, aoffsetp);
    517 	  disp2 = get_displacement (buffer, aoffsetp);
    518 	  sprintf (result, "%d(%d(%s))", disp2, disp1,
    519 		   addr_mode == 0x10 ? "fp" : addr_mode == 0x11 ? "sp" : "sb");
    520 	  break;
    521 	case 0x13:
    522 	  /* Reserved.  */
    523 	  sprintf (result, "reserved");
    524 	  break;
    525 	case 0x14:
    526 	  /* Immediate.  */
    527 	  switch (d)
    528 	    {
    529 	    case 'I':
    530 	    case 'Z':
    531 	    case 'A':
    532 	      /* I and Z are output operands and can`t be immediate
    533 	         A is an address and we can`t have the address of
    534 	         an immediate either. We don't know how much to increase
    535 	         aoffsetp by since whatever generated this is broken
    536 	         anyway!  */
    537 	      sprintf (result, _("$<undefined>"));
    538 	      break;
    539 	    case 'B':
    540 	      Ivalue = bit_extract (buffer, *aoffsetp, 8);
    541 	      Ivalue = sign_extend (Ivalue, 8);
    542 	      *aoffsetp += 8;
    543 	      sprintf (result, "$%d", Ivalue);
    544 	      break;
    545 	    case 'W':
    546 	      Ivalue = bit_extract (buffer, *aoffsetp, 16);
    547 	      flip_bytes ((char *) & Ivalue, 2);
    548 	      *aoffsetp += 16;
    549 	      Ivalue = sign_extend (Ivalue, 16);
    550 	      sprintf (result, "$%d", Ivalue);
    551 	      break;
    552 	    case 'D':
    553 	      Ivalue = bit_extract (buffer, *aoffsetp, 32);
    554 	      flip_bytes ((char *) & Ivalue, 4);
    555 	      *aoffsetp += 32;
    556 	      sprintf (result, "$%d", Ivalue);
    557 	      break;
    558 	    case 'F':
    559 	      bit_copy (buffer, *aoffsetp, 32, (char *) &value.f);
    560 	      flip_bytes ((char *) &value.f, 4);
    561 	      *aoffsetp += 32;
    562 	      if (INVALID_FLOAT (&value.f, 4))
    563 		sprintf (result, "<<invalid float 0x%.8x>>", value.i[0]);
    564 	      else /* Assume host has ieee float.  */
    565 		sprintf (result, "$%g", value.f);
    566 	      break;
    567 	    case 'L':
    568 	      bit_copy (buffer, *aoffsetp, 64, (char *) &value.d);
    569 	      flip_bytes ((char *) &value.d, 8);
    570 	      *aoffsetp += 64;
    571 	      if (INVALID_FLOAT (&value.d, 8))
    572 		sprintf (result, "<<invalid double 0x%.8x%.8x>>",
    573 			 value.i[1], value.i[0]);
    574 	      else /* Assume host has ieee float.  */
    575 		sprintf (result, "$%g", value.d);
    576 	      break;
    577 	    }
    578 	  break;
    579 	case 0x15:
    580 	  /* Absolute @disp.  */
    581 	  disp1 = get_displacement (buffer, aoffsetp);
    582 	  sprintf (result, "@|%d|", disp1);
    583 	  break;
    584 	case 0x16:
    585 	  /* External EXT(disp1) + disp2 (Mod table stuff).  */
    586 	  disp1 = get_displacement (buffer, aoffsetp);
    587 	  disp2 = get_displacement (buffer, aoffsetp);
    588 	  sprintf (result, "EXT(%d) + %d", disp1, disp2);
    589 	  break;
    590 	case 0x17:
    591 	  /* Top of stack tos.  */
    592 	  sprintf (result, "tos");
    593 	  break;
    594 	case 0x18:
    595 	  /* Memory space disp(FP).  */
    596 	  disp1 = get_displacement (buffer, aoffsetp);
    597 	  sprintf (result, "%d(fp)", disp1);
    598 	  break;
    599 	case 0x19:
    600 	  /* Memory space disp(SP).  */
    601 	  disp1 = get_displacement (buffer, aoffsetp);
    602 	  sprintf (result, "%d(sp)", disp1);
    603 	  break;
    604 	case 0x1a:
    605 	  /* Memory space disp(SB).  */
    606 	  disp1 = get_displacement (buffer, aoffsetp);
    607 	  sprintf (result, "%d(sb)", disp1);
    608 	  break;
    609 	case 0x1b:
    610 	  /* Memory space disp(PC).  */
    611 	  disp1 = get_displacement (buffer, aoffsetp);
    612 	  *result++ = NEXT_IS_ADDR;
    613 	  sprintf_vma (result, addr + disp1);
    614 	  result += strlen (result);
    615 	  *result++ = NEXT_IS_ADDR;
    616 	  *result = '\0';
    617 	  break;
    618 	case 0x1c:
    619 	case 0x1d:
    620 	case 0x1e:
    621 	case 0x1f:
    622 	  {
    623 	    int bit_index;
    624 	    static const char *ind = "bwdq";
    625 	    char *off;
    626 
    627 	    /* Scaled index basemode[R0 -- R7:B,W,D,Q].  */
    628 	    bit_index = bit_extract (buffer, index_offset - 8, 3);
    629 	    print_insn_arg (d, index_offset, aoffsetp, buffer, addr,
    630 			    result, 0);
    631 	    off = result + strlen (result);
    632 	    sprintf (off, "[r%d:%c]", bit_index, ind[addr_mode & 3]);
    633 	  }
    634 	  break;
    635 	}
    636       break;
    637     case 'H':
    638     case 'q':
    639       Ivalue = bit_extract (buffer, ioffset-4, 4);
    640       Ivalue = sign_extend (Ivalue, 4);
    641       sprintf (result, "%d", Ivalue);
    642       ioffset -= 4;
    643       break;
    644     case 'r':
    645       Ivalue = bit_extract (buffer, ioffset-3, 3);
    646       sprintf (result, "r%d", Ivalue&7);
    647       ioffset -= 3;
    648       break;
    649     case 'd':
    650       sprintf (result, "%d", get_displacement (buffer, aoffsetp));
    651       break;
    652     case 'b':
    653       Ivalue = get_displacement (buffer, aoffsetp);
    654       /* Warning!!  HACK ALERT!
    655          Operand type 'b' is only used by the cmp{b,w,d} and
    656          movm{b,w,d} instructions; we need to know whether
    657          it's a `b' or `w' or `d' instruction; and for both
    658          cmpm and movm it's stored at the same place so we
    659          just grab two bits of the opcode and look at it...  */
    660       size = bit_extract(buffer, ioffset-6, 2);
    661       if (size == 0)		/* 00 => b.  */
    662 	size = 1;
    663       else if (size == 1)	/* 01 => w.  */
    664 	size = 2;
    665       else
    666 	size = 4;		/* 11 => d.  */
    667 
    668       sprintf (result, "%d", (Ivalue / size) + 1);
    669       break;
    670     case 'p':
    671       *result++ = NEXT_IS_ADDR;
    672       sprintf_vma (result, addr + get_displacement (buffer, aoffsetp));
    673       result += strlen (result);
    674       *result++ = NEXT_IS_ADDR;
    675       *result = '\0';
    676       break;
    677     case 'i':
    678       Ivalue = bit_extract (buffer, *aoffsetp, 8);
    679       *aoffsetp += 8;
    680       sprintf (result, "0x%x", Ivalue);
    681       break;
    682     case 'u':
    683       Ivalue = bit_extract (buffer, *aoffsetp, 8);
    684       optlist (Ivalue, opt_u, result);
    685       *aoffsetp += 8;
    686       break;
    687     case 'U':
    688       Ivalue = bit_extract (buffer, *aoffsetp, 8);
    689       optlist (Ivalue, opt_U, result);
    690       *aoffsetp += 8;
    691       break;
    692     case 'O':
    693       Ivalue = bit_extract (buffer, ioffset - 9, 9);
    694       optlist (Ivalue, opt_O, result);
    695       ioffset -= 9;
    696       break;
    697     case 'C':
    698       Ivalue = bit_extract (buffer, ioffset - 4, 4);
    699       optlist (Ivalue, opt_C, result);
    700       ioffset -= 4;
    701       break;
    702     case 'S':
    703       Ivalue = bit_extract (buffer, ioffset - 8, 8);
    704       optlist (Ivalue, opt_S, result);
    705       ioffset -= 8;
    706       break;
    707     case 'M':
    708       Ivalue = bit_extract (buffer, ioffset - 4, 4);
    709       list_search (Ivalue, 0 ? list_M032 : list_M532, result);
    710       ioffset -= 4;
    711       break;
    712     case 'P':
    713       Ivalue = bit_extract (buffer, ioffset - 4, 4);
    714       list_search (Ivalue, 0 ? list_P032 : list_P532, result);
    715       ioffset -= 4;
    716       break;
    717     case 'g':
    718       Ivalue = bit_extract (buffer, *aoffsetp, 3);
    719       sprintf (result, "%d", Ivalue);
    720       *aoffsetp += 3;
    721       break;
    722     case 'G':
    723       Ivalue = bit_extract(buffer, *aoffsetp, 5);
    724       sprintf (result, "%d", Ivalue + 1);
    725       *aoffsetp += 5;
    726       break;
    727     }
    728   return ioffset;
    729 }
    730 
    731 
    732 /* Print the 32000 instruction at address MEMADDR in debugged memory,
    734    on STREAM.  Returns length of the instruction, in bytes.  */
    735 
    736 int
    737 print_insn_ns32k (bfd_vma memaddr, disassemble_info *info)
    738 {
    739   unsigned int i;
    740   const char *d;
    741   unsigned short first_word;
    742   int ioffset;		/* Bits into instruction.  */
    743   int aoffset;		/* Bits into arguments.  */
    744   char arg_bufs[MAX_ARGS+1][ARG_LEN];
    745   int argnum;
    746   int maxarg;
    747   struct private priv;
    748   bfd_byte *buffer = priv.the_buffer;
    749   dis_info = info;
    750 
    751   info->private_data = & priv;
    752   priv.max_fetched = priv.the_buffer;
    753   priv.insn_start = memaddr;
    754   if (OPCODES_SIGSETJMP (priv.bailout) != 0)
    755     /* Error return.  */
    756     return -1;
    757 
    758   /* Look for 8bit opcodes first. Other wise, fetching two bytes could take
    759      us over the end of accessible data unnecessarilly.  */
    760   FETCH_DATA (info, buffer + 1);
    761   for (i = 0; i < NOPCODES; i++)
    762     if (ns32k_opcodes[i].opcode_id_size <= 8
    763 	&& ((buffer[0]
    764 	     & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
    765 	    == ns32k_opcodes[i].opcode_seed))
    766       break;
    767   if (i == NOPCODES)
    768     {
    769       /* Maybe it is 9 to 16 bits big.  */
    770       FETCH_DATA (info, buffer + 2);
    771       first_word = read_memory_integer(buffer, 2);
    772 
    773       for (i = 0; i < NOPCODES; i++)
    774 	if ((first_word
    775 	     & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
    776 	    == ns32k_opcodes[i].opcode_seed)
    777 	  break;
    778 
    779       /* Handle undefined instructions.  */
    780       if (i == NOPCODES)
    781 	{
    782 	  (*dis_info->fprintf_func)(dis_info->stream, "0%o", buffer[0]);
    783 	  return 1;
    784 	}
    785     }
    786 
    787   (*dis_info->fprintf_func)(dis_info->stream, "%s", ns32k_opcodes[i].name);
    788 
    789   ioffset = ns32k_opcodes[i].opcode_size;
    790   aoffset = ns32k_opcodes[i].opcode_size;
    791   d = ns32k_opcodes[i].operands;
    792 
    793   if (*d)
    794     {
    795       /* Offset in bits of the first thing beyond each index byte.
    796 	 Element 0 is for operand A and element 1 is for operand B.
    797 	 The rest are irrelevant, but we put them here so we don't
    798 	 index outside the array.  */
    799       int index_offset[MAX_ARGS];
    800 
    801       /* 0 for operand A, 1 for operand B, greater for other args.  */
    802       int whicharg = 0;
    803 
    804       (*dis_info->fprintf_func)(dis_info->stream, "\t");
    805 
    806       maxarg = 0;
    807 
    808       /* First we have to find and keep track of the index bytes,
    809 	 if we are using scaled indexed addressing mode, since the index
    810 	 bytes occur right after the basic instruction, not as part
    811 	 of the addressing extension.  */
    812       if (Is_gen(d[1]))
    813 	{
    814 	  int addr_mode = bit_extract (buffer, ioffset - 5, 5);
    815 
    816 	  if (Adrmod_is_index (addr_mode))
    817 	    {
    818 	      aoffset += 8;
    819 	      index_offset[0] = aoffset;
    820 	    }
    821 	}
    822 
    823       if (d[2] && Is_gen(d[3]))
    824 	{
    825 	  int addr_mode = bit_extract (buffer, ioffset - 10, 5);
    826 
    827 	  if (Adrmod_is_index (addr_mode))
    828 	    {
    829 	      aoffset += 8;
    830 	      index_offset[1] = aoffset;
    831 	    }
    832 	}
    833 
    834       while (*d)
    835 	{
    836 	  argnum = *d - '1';
    837 	  d++;
    838 	  if (argnum > maxarg && argnum < MAX_ARGS)
    839 	    maxarg = argnum;
    840 	  ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer,
    841 				    memaddr, arg_bufs[argnum],
    842 				    index_offset[whicharg]);
    843 	  d++;
    844 	  whicharg++;
    845 	}
    846       for (argnum = 0; argnum <= maxarg; argnum++)
    847 	{
    848 	  bfd_vma addr;
    849 	  char *ch;
    850 
    851 	  for (ch = arg_bufs[argnum]; *ch;)
    852 	    {
    853 	      if (*ch == NEXT_IS_ADDR)
    854 		{
    855 		  ++ch;
    856 		  addr = bfd_scan_vma (ch, NULL, 16);
    857 		  (*dis_info->print_address_func) (addr, dis_info);
    858 		  while (*ch && *ch != NEXT_IS_ADDR)
    859 		    ++ch;
    860 		  if (*ch)
    861 		    ++ch;
    862 		}
    863 	      else
    864 		(*dis_info->fprintf_func)(dis_info->stream, "%c", *ch++);
    865 	    }
    866 	  if (argnum < maxarg)
    867 	    (*dis_info->fprintf_func)(dis_info->stream, ", ");
    868 	}
    869     }
    870   return aoffset / 8;
    871 }
    872