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