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