Home | History | Annotate | Line # | Download | only in opcodes
ns32k-dis.c revision 1.1.1.9
      1 /* Print National Semiconductor 32000 instructions.
      2    Copyright (C) 1986-2025 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   unsigned int result;
    269   unsigned int bit;
    270 
    271   if (offset < 0 || count < 0)
    272     return 0;
    273   buffer += offset >> 3;
    274   offset &= 7;
    275   bit = 1;
    276   result = 0;
    277   while (count--)
    278     {
    279       FETCH_DATA (dis_info, buffer + 1);
    280       if ((*buffer & (1 << offset)))
    281 	result |= bit;
    282       if (++offset == 8)
    283 	{
    284 	  offset = 0;
    285 	  buffer++;
    286 	}
    287       bit <<= 1;
    288     }
    289   return result;
    290 }
    291 
    292 /* Like bit extract but the buffer is valid and doen't need to be fetched.  */
    293 
    294 static int
    295 bit_extract_simple (bfd_byte *buffer, int offset, int count)
    296 {
    297   unsigned int result;
    298   unsigned int bit;
    299 
    300   if (offset < 0 || count < 0)
    301     return 0;
    302   buffer += offset >> 3;
    303   offset &= 7;
    304   bit = 1;
    305   result = 0;
    306   while (count--)
    307     {
    308       if ((*buffer & (1 << offset)))
    309 	result |= bit;
    310       if (++offset == 8)
    311 	{
    312 	  offset = 0;
    313 	  buffer++;
    314 	}
    315       bit <<= 1;
    316     }
    317   return result;
    318 }
    319 
    320 static void
    321 bit_copy (bfd_byte *buffer, int offset, int count, char *to)
    322 {
    323   if (offset < 0 || count < 0)
    324     return;
    325   for (; count > 8; count -= 8, to++, offset += 8)
    326     *to = bit_extract (buffer, offset, 8);
    327   *to = bit_extract (buffer, offset, count);
    328 }
    329 
    330 static int
    331 sign_extend (unsigned int value, unsigned int bits)
    332 {
    333   unsigned int sign = 1u << (bits - 1);
    334   return ((value & (sign + sign - 1)) ^ sign) - sign;
    335 }
    336 
    337 static void
    338 flip_bytes (char *ptr, int count)
    339 {
    340   char tmp;
    341 
    342   while (count > 0)
    343     {
    344       tmp = ptr[0];
    345       ptr[0] = ptr[count - 1];
    346       ptr[count - 1] = tmp;
    347       ptr++;
    348       count -= 2;
    349     }
    350 }
    351 
    352 /* Given a character C, does it represent a general addressing mode?  */
    354 #define Is_gen(c) (strchr ("FLBWDAIZf", (c)) != NULL)
    355 
    356 /* Adressing modes.  */
    357 #define Adrmod_index_byte        0x1c
    358 #define Adrmod_index_word        0x1d
    359 #define Adrmod_index_doubleword  0x1e
    360 #define Adrmod_index_quadword    0x1f
    361 
    362 /* Is MODE an indexed addressing mode?  */
    363 #define Adrmod_is_index(mode) \
    364   (   mode == Adrmod_index_byte \
    365    || mode == Adrmod_index_word \
    366    || mode == Adrmod_index_doubleword \
    367    || mode == Adrmod_index_quadword)
    368 
    369 
    370 static int
    372 get_displacement (bfd_byte *buffer, int *aoffsetp)
    373 {
    374   int Ivalue;
    375   short Ivalue2;
    376 
    377   Ivalue = bit_extract (buffer, *aoffsetp, 8);
    378   switch (Ivalue & 0xc0)
    379     {
    380     case 0x00:
    381     case 0x40:
    382       Ivalue = sign_extend (Ivalue, 7);
    383       *aoffsetp += 8;
    384       break;
    385     case 0x80:
    386       Ivalue2 = bit_extract (buffer, *aoffsetp, 16);
    387       flip_bytes ((char *) & Ivalue2, 2);
    388       Ivalue = sign_extend (Ivalue2, 14);
    389       *aoffsetp += 16;
    390       break;
    391     case 0xc0:
    392       Ivalue = bit_extract (buffer, *aoffsetp, 32);
    393       flip_bytes ((char *) & Ivalue, 4);
    394       Ivalue = sign_extend (Ivalue, 30);
    395       *aoffsetp += 32;
    396       break;
    397     }
    398   return Ivalue;
    399 }
    400 
    401 #if 1 /* A version that should work on ns32k f's&d's on any machine.  */
    402 static int
    403 invalid_float (bfd_byte *p, int len)
    404 {
    405   int val;
    406 
    407   if (len == 4)
    408     val = (bit_extract_simple (p, 23, 8)/*exponent*/ == 0xff
    409 	   || (bit_extract_simple (p, 23, 8)/*exponent*/ == 0
    410 	       && bit_extract_simple (p, 0, 23)/*mantisa*/ != 0));
    411   else if (len == 8)
    412     val = (bit_extract_simple (p, 52, 11)/*exponent*/ == 0x7ff
    413 	   || (bit_extract_simple (p, 52, 11)/*exponent*/ == 0
    414 	       && (bit_extract_simple (p, 0, 32)/*low mantisa*/ != 0
    415 		   || bit_extract_simple (p, 32, 20)/*high mantisa*/ != 0)));
    416   else
    417     val = 1;
    418   return (val);
    419 }
    420 #else
    421 /* Assumes the bytes have been swapped to local order.  */
    422 typedef union
    423 {
    424   double d;
    425   float f;
    426   struct { unsigned m:23, e:8, :1;} sf;
    427   struct { unsigned lm; unsigned m:20, e:11, :1;} sd;
    428 } float_type_u;
    429 
    430 static int
    431 invalid_float (float_type_u *p, int len)
    432 {
    433   int val;
    434 
    435   if (len == sizeof (float))
    436     val = (p->sf.e == 0xff
    437 	   || (p->sf.e == 0 && p->sf.m != 0));
    438   else if (len == sizeof (double))
    439     val = (p->sd.e == 0x7ff
    440 	   || (p->sd.e == 0 && (p->sd.m != 0 || p->sd.lm != 0)));
    441   else
    442     val = 1;
    443   return val;
    444 }
    445 #endif
    446 
    447 /* Print an instruction operand of category given by d.  IOFFSET is
    448    the bit position below which small (<1 byte) parts of the operand can
    449    be found (usually in the basic instruction, but for indexed
    450    addressing it can be in the index byte).  AOFFSETP is a pointer to the
    451    bit position of the addressing extension.  BUFFER contains the
    452    instruction.  ADDR is where BUFFER was read from.  Put the disassembled
    453    version of the operand in RESULT.  INDEX_OFFSET is the bit position
    454    of the index byte (it contains -1 if this operand is not a
    455    general operand using scaled indexed addressing mode).  */
    456 
    457 static int
    458 print_insn_arg (int d,
    459 		int ioffset,
    460 		int *aoffsetp,
    461 		bfd_byte *buffer,
    462 		bfd_vma addr,
    463 		char *result,
    464 		int index_offset)
    465 {
    466   union
    467   {
    468     float f;
    469     double d;
    470     int i[2];
    471   } value;
    472   int Ivalue;
    473   int addr_mode;
    474   int disp1, disp2;
    475   int size;
    476 
    477   switch (d)
    478     {
    479     case 'f':
    480       /* A "gen" operand but 5 bits from the end of instruction.  */
    481       ioffset -= 5;
    482       /* Fall through.  */
    483     case 'Z':
    484     case 'F':
    485     case 'L':
    486     case 'I':
    487     case 'B':
    488     case 'W':
    489     case 'D':
    490     case 'A':
    491       addr_mode = bit_extract (buffer, ioffset - 5, 5);
    492       ioffset -= 5;
    493       switch (addr_mode)
    494 	{
    495 	case 0x0: case 0x1: case 0x2: case 0x3:
    496 	case 0x4: case 0x5: case 0x6: case 0x7:
    497 	  /* Register mode R0 -- R7.  */
    498 	  switch (d)
    499 	    {
    500 	    case 'F':
    501 	    case 'L':
    502 	    case 'Z':
    503 	      sprintf (result, "f%d", addr_mode);
    504 	      break;
    505 	    default:
    506 	      sprintf (result, "r%d", addr_mode);
    507 	    }
    508 	  break;
    509 	case 0x8: case 0x9: case 0xa: case 0xb:
    510 	case 0xc: case 0xd: case 0xe: case 0xf:
    511 	  /* Register relative disp(R0 -- R7).  */
    512 	  disp1 = get_displacement (buffer, aoffsetp);
    513 	  sprintf (result, "%d(r%d)", disp1, addr_mode & 7);
    514 	  break;
    515 	case 0x10:
    516 	case 0x11:
    517 	case 0x12:
    518 	  /* Memory relative disp2(disp1(FP, SP, SB)).  */
    519 	  disp1 = get_displacement (buffer, aoffsetp);
    520 	  disp2 = get_displacement (buffer, aoffsetp);
    521 	  sprintf (result, "%d(%d(%s))", disp2, disp1,
    522 		   addr_mode == 0x10 ? "fp" : addr_mode == 0x11 ? "sp" : "sb");
    523 	  break;
    524 	case 0x13:
    525 	  /* Reserved.  */
    526 	  sprintf (result, "reserved");
    527 	  break;
    528 	case 0x14:
    529 	  /* Immediate.  */
    530 	  switch (d)
    531 	    {
    532 	    default:
    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 (result, "%" PRIx64, (uint64_t) (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 (result, "%" PRIx64,
    674 	       (uint64_t) (addr + get_displacement (buffer, aoffsetp)));
    675       result += strlen (result);
    676       *result++ = NEXT_IS_ADDR;
    677       *result = '\0';
    678       break;
    679     case 'i':
    680       Ivalue = bit_extract (buffer, *aoffsetp, 8);
    681       *aoffsetp += 8;
    682       sprintf (result, "0x%x", Ivalue);
    683       break;
    684     case 'u':
    685       Ivalue = bit_extract (buffer, *aoffsetp, 8);
    686       optlist (Ivalue, opt_u, result);
    687       *aoffsetp += 8;
    688       break;
    689     case 'U':
    690       Ivalue = bit_extract (buffer, *aoffsetp, 8);
    691       optlist (Ivalue, opt_U, result);
    692       *aoffsetp += 8;
    693       break;
    694     case 'O':
    695       Ivalue = bit_extract (buffer, ioffset - 9, 9);
    696       optlist (Ivalue, opt_O, result);
    697       ioffset -= 9;
    698       break;
    699     case 'C':
    700       Ivalue = bit_extract (buffer, ioffset - 4, 4);
    701       optlist (Ivalue, opt_C, result);
    702       ioffset -= 4;
    703       break;
    704     case 'S':
    705       Ivalue = bit_extract (buffer, ioffset - 8, 8);
    706       optlist (Ivalue, opt_S, result);
    707       ioffset -= 8;
    708       break;
    709     case 'M':
    710       Ivalue = bit_extract (buffer, ioffset - 4, 4);
    711       list_search (Ivalue, 0 ? list_M032 : list_M532, result);
    712       ioffset -= 4;
    713       break;
    714     case 'P':
    715       Ivalue = bit_extract (buffer, ioffset - 4, 4);
    716       list_search (Ivalue, 0 ? list_P032 : list_P532, result);
    717       ioffset -= 4;
    718       break;
    719     case 'g':
    720       Ivalue = bit_extract (buffer, *aoffsetp, 3);
    721       sprintf (result, "%d", Ivalue);
    722       *aoffsetp += 3;
    723       break;
    724     case 'G':
    725       Ivalue = bit_extract(buffer, *aoffsetp, 5);
    726       sprintf (result, "%d", Ivalue + 1);
    727       *aoffsetp += 5;
    728       break;
    729     }
    730   return ioffset;
    731 }
    732 
    733 
    734 /* Print the 32000 instruction at address MEMADDR in debugged memory,
    736    on STREAM.  Returns length of the instruction, in bytes.  */
    737 
    738 int
    739 print_insn_ns32k (bfd_vma memaddr, disassemble_info *info)
    740 {
    741   unsigned int i;
    742   const char *d;
    743   unsigned short first_word;
    744   int ioffset;		/* Bits into instruction.  */
    745   int aoffset;		/* Bits into arguments.  */
    746   char arg_bufs[MAX_ARGS+1][ARG_LEN];
    747   int argnum;
    748   int maxarg;
    749   struct private priv;
    750   bfd_byte *buffer = priv.the_buffer;
    751   dis_info = info;
    752 
    753   info->private_data = & priv;
    754   priv.max_fetched = priv.the_buffer;
    755   priv.insn_start = memaddr;
    756   if (OPCODES_SIGSETJMP (priv.bailout) != 0)
    757     /* Error return.  */
    758     return -1;
    759 
    760   /* Look for 8bit opcodes first. Other wise, fetching two bytes could take
    761      us over the end of accessible data unnecessarilly.  */
    762   FETCH_DATA (info, buffer + 1);
    763   for (i = 0; i < NOPCODES; i++)
    764     if (ns32k_opcodes[i].opcode_id_size <= 8
    765 	&& ((buffer[0]
    766 	     & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
    767 	    == ns32k_opcodes[i].opcode_seed))
    768       break;
    769   if (i == NOPCODES)
    770     {
    771       /* Maybe it is 9 to 16 bits big.  */
    772       FETCH_DATA (info, buffer + 2);
    773       first_word = read_memory_integer(buffer, 2);
    774 
    775       for (i = 0; i < NOPCODES; i++)
    776 	if ((first_word
    777 	     & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
    778 	    == ns32k_opcodes[i].opcode_seed)
    779 	  break;
    780 
    781       /* Handle undefined instructions.  */
    782       if (i == NOPCODES)
    783 	{
    784 	  (*dis_info->fprintf_func)(dis_info->stream, "0%o", buffer[0]);
    785 	  return 1;
    786 	}
    787     }
    788 
    789   (*dis_info->fprintf_func)(dis_info->stream, "%s", ns32k_opcodes[i].name);
    790 
    791   ioffset = ns32k_opcodes[i].opcode_size;
    792   aoffset = ns32k_opcodes[i].opcode_size;
    793   d = ns32k_opcodes[i].operands;
    794 
    795   if (*d)
    796     {
    797       /* Offset in bits of the first thing beyond each index byte.
    798 	 Element 0 is for operand A and element 1 is for operand B.  */
    799       int index_offset[2];
    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       index_offset[0] = -1;
    813       index_offset[1] = -1;
    814       if (Is_gen (d[1]))
    815 	{
    816 	  int bitoff = d[1] == 'f' ? 10 : 5;
    817 	  int addr_mode = bit_extract (buffer, ioffset - bitoff, 5);
    818 
    819 	  if (Adrmod_is_index (addr_mode))
    820 	    {
    821 	      aoffset += 8;
    822 	      index_offset[0] = aoffset;
    823 	    }
    824 	}
    825 
    826       if (d[2] && Is_gen (d[3]))
    827 	{
    828 	  int addr_mode = bit_extract (buffer, ioffset - 10, 5);
    829 
    830 	  if (Adrmod_is_index (addr_mode))
    831 	    {
    832 	      aoffset += 8;
    833 	      index_offset[1] = aoffset;
    834 	    }
    835 	}
    836 
    837       while (*d)
    838 	{
    839 	  argnum = *d - '1';
    840 	  if (argnum >= MAX_ARGS)
    841 	    abort ();
    842 	  d++;
    843 	  if (argnum > maxarg)
    844 	    maxarg = argnum;
    845 	  ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer,
    846 				    memaddr, arg_bufs[argnum],
    847 				    whicharg > 1 ? -1 : index_offset[whicharg]);
    848 	  d++;
    849 	  whicharg++;
    850 	}
    851 
    852       for (argnum = 0; argnum <= maxarg; argnum++)
    853 	{
    854 	  bfd_vma addr;
    855 	  char *ch;
    856 
    857 	  for (ch = arg_bufs[argnum]; *ch;)
    858 	    {
    859 	      if (*ch == NEXT_IS_ADDR)
    860 		{
    861 		  ++ch;
    862 		  addr = bfd_scan_vma (ch, NULL, 16);
    863 		  (*dis_info->print_address_func) (addr, dis_info);
    864 		  while (*ch && *ch != NEXT_IS_ADDR)
    865 		    ++ch;
    866 		  if (*ch)
    867 		    ++ch;
    868 		}
    869 	      else
    870 		(*dis_info->fprintf_func)(dis_info->stream, "%c", *ch++);
    871 	    }
    872 	  if (argnum < maxarg)
    873 	    (*dis_info->fprintf_func)(dis_info->stream, ", ");
    874 	}
    875     }
    876   return aoffset / 8;
    877 }
    878