Update the address and phone number of the FSF
[external/binutils.git] / opcodes / ns32k-dis.c
1 /* Print National Semiconductor 32000 instructions.
2    Copyright 1986, 1988, 1991, 1992, 1994, 1998, 2001, 2002, 2005
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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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((bfd_byte *)val, size)
37
38 static int print_insn_arg
39   PARAMS ((int, int, int *, bfd_byte *, bfd_vma, char *, int));
40 static int get_displacement PARAMS ((bfd_byte *, int *));
41 static int invalid_float PARAMS ((bfd_byte *, 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 ((bfd_byte *, 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 \f
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 \f
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 \f
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      bfd_byte *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 \f
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 \f
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      bfd_byte *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      bfd_byte *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 \f
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 bfd_byte *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