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