Avoid bogus assumption that the two parts of the split m68k opcode table
[platform/upstream/binutils.git] / opcodes / m68k-dis.c
1 /* Print Motorola 68k instructions.
2    Copyright 1986, 1987, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
3
4 This file is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
17
18 #include "dis-asm.h"
19 #include "floatformat.h"
20
21 /* Opcode/m68k.h is a massive table.  As a kludge, break it up into
22    two pieces.  This makes nonportable C -- FIXME -- it assumes that
23    two data items declared near each other will be contiguous in
24    memory.  This kludge can be removed, FIXME, when GCC is fixed to not
25    be a hog about initializers.  */
26
27 #ifdef __GNUC__
28 #define BREAK_UP_BIG_DECL       }; \
29                                 struct m68k_opcode m68k_opcodes_2[] = {
30 #define AND_OTHER_PART          sizeof (m68k_opcodes_2)
31 #endif
32
33 #include "opcode/m68k.h"
34
35
36 /* Local function prototypes */
37
38 static int
39 fetch_arg PARAMS ((unsigned char *, int, int, disassemble_info *));
40
41 static void
42 print_base PARAMS ((int, int, disassemble_info*));
43
44 static unsigned char *
45 print_indexed PARAMS ((int, unsigned char *, bfd_vma, disassemble_info *));
46
47 static int
48 print_insn_arg PARAMS ((char *, unsigned char *, unsigned char *, bfd_vma,
49                         disassemble_info *));
50
51 CONST char * CONST fpcr_names[] = {
52   "", "fpiar", "fpsr", "fpiar/fpsr", "fpcr",
53   "fpiar/fpcr", "fpsr/fpcr", "fpiar/fpsr/fpcr"};
54
55 static char *reg_names[] = {
56   "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "a0",
57   "a1", "a2", "a3", "a4", "a5", "fp", "sp", "ps", "pc"};
58
59 /* Sign-extend an (unsigned char). */
60 #if __STDC__ == 1
61 #define COERCE_SIGNED_CHAR(ch) ((signed char)(ch))
62 #else
63 #define COERCE_SIGNED_CHAR(ch) ((int)(((ch) ^ 0x80) & 0xFF) - 128)
64 #endif
65
66 /* Get a 1 byte signed integer.  */
67 #define NEXTBYTE(p)  (p += 2, FETCH_DATA (info, p), COERCE_SIGNED_CHAR(p[-1]))
68
69 /* Get a 2 byte signed integer.  */
70 #define COERCE16(x) ((int) (((x) ^ 0x8000) - 0x8000))
71 #define NEXTWORD(p)  \
72   (p += 2, FETCH_DATA (info, p), \
73    COERCE16 ((p[-2] << 8) + p[-1]))
74
75 /* Get a 4 byte signed integer.  */
76 #define COERCE32(x) ((int) (((x) ^ 0x80000000) - 0x80000000))
77 #define NEXTLONG(p)  \
78   (p += 4, FETCH_DATA (info, p), \
79    (COERCE32 ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])))
80
81 /* NEXTSINGLE and NEXTDOUBLE handle alignment problems, but not
82  * byte-swapping or other float format differences.  FIXME! */
83
84 union number {
85     double d;
86     float f;
87     char c[10];
88 };
89
90 #define NEXTSINGLE(val, p) \
91   { int i; union number u;\
92     FETCH_DATA (info, p + sizeof (float));\
93     for (i = 0; i < sizeof(float); i++) u.c[i] = *p++; \
94     val = u.f; }
95
96 #define NEXTDOUBLE(val, p) \
97   { int i; union number u;\
98     FETCH_DATA (info, p + sizeof (double));\
99     for (i = 0; i < sizeof(double); i++) u.c[i] = *p++; \
100     val = u.d; }
101
102 /* Need a function to convert from extended to double precision... */
103 #define NEXTEXTEND(p) \
104   (p += 12, FETCH_DATA (info, p), 0.0)
105
106 /* Need a function to convert from packed to double
107    precision.   Actually, it's easier to print a
108    packed number than a double anyway, so maybe
109    there should be a special case to handle this... */
110 #define NEXTPACKED(p) \
111   (p += 12, FETCH_DATA (info, p), 0.0)
112
113 \f
114 /* Maximum length of an instruction.  */
115 #define MAXLEN 22
116
117 #include <setjmp.h>
118
119 struct private
120 {
121   /* Points to first byte not fetched.  */
122   bfd_byte *max_fetched;
123   bfd_byte the_buffer[MAXLEN];
124   bfd_vma insn_start;
125   jmp_buf bailout;
126 };
127
128 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
129    to ADDR (exclusive) are valid.  Returns 1 for success, longjmps
130    on error.  */
131 #define FETCH_DATA(info, addr) \
132   ((addr) <= ((struct private *)(info->private_data))->max_fetched \
133    ? 1 : fetch_data ((info), (addr)))
134
135 static int
136 fetch_data (info, addr)
137      struct disassemble_info *info;
138      bfd_byte *addr;
139 {
140   int status;
141   struct private *priv = (struct private *)info->private_data;
142   bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
143
144   status = (*info->read_memory_func) (start,
145                                       priv->max_fetched,
146                                       addr - priv->max_fetched,
147                                       info);
148   if (status != 0)
149     {
150       (*info->memory_error_func) (status, start, info);
151       longjmp (priv->bailout, 1);
152     }
153   else
154     priv->max_fetched = addr;
155   return 1;
156 }
157 \f
158 /* This function is used to print to the bit-bucket. */
159 static int
160 #ifdef __STDC__
161 dummy_printer (FILE * file, const char * format, ...)
162 #else
163 dummy_printer (file) FILE *file;
164 #endif
165  { return 0; }
166
167 void
168 dummy_print_address (vma, info)
169      bfd_vma vma;
170      struct disassemble_info *info;
171 {
172 }
173
174 static const struct m68k_opcode *
175 opcode (idx)
176      int idx;
177 {
178 #ifdef __GNUC__
179   const int max = sizeof (m68k_opcodes) / sizeof (m68k_opcodes[0]);
180   if (idx >= max)
181     return &m68k_opcodes_2[idx - max];
182 #endif
183   return &m68k_opcodes[idx];
184 }
185
186 /* Print the m68k instruction at address MEMADDR in debugged memory,
187    on INFO->STREAM.  Returns length of the instruction, in bytes.  */
188
189 int
190 print_insn_m68k (memaddr, info)
191      bfd_vma memaddr;
192      disassemble_info *info;
193 {
194   register int i;
195   register unsigned char *p;
196   unsigned char *save_p;
197   register char *d;
198   register unsigned long bestmask;
199   const struct m68k_opcode *best = 0;
200   struct private priv;
201   bfd_byte *buffer = priv.the_buffer;
202   fprintf_ftype save_printer = info->fprintf_func;
203   void (*save_print_address) PARAMS((bfd_vma, struct disassemble_info*))
204     = info->print_address_func;
205
206   info->private_data = (PTR) &priv;
207   priv.max_fetched = priv.the_buffer;
208   priv.insn_start = memaddr;
209   if (setjmp (priv.bailout) != 0)
210     /* Error return.  */
211     return -1;
212
213   bestmask = 0;
214   FETCH_DATA (info, buffer + 2);
215   for (i = 0; i < numopcodes; i++)
216     {
217       const struct m68k_opcode *opc = opcode (i);
218       unsigned long opcode = opc->opcode;
219       unsigned long match = opc->match;
220
221       if (opc->flags & F_ALIAS)
222         continue;
223
224       if (((0xff & buffer[0] & (match >> 24)) == (0xff & (opcode >> 24)))
225           && ((0xff & buffer[1] & (match >> 16)) == (0xff & (opcode >> 16)))
226           /* Only fetch the next two bytes if we need to.  */
227           && (((0xffff & match) == 0)
228               ||
229               (FETCH_DATA (info, buffer + 4)
230                && ((0xff & buffer[2] & (match >> 8)) == (0xff & (opcode >> 8)))
231                && ((0xff & buffer[3] & match) == (0xff & opcode)))
232               ))
233         {
234           /* Don't use for printout the variants of divul and divsl
235              that have the same register number in two places.
236              The more general variants will match instead.  */
237           for (d = opc->args; *d; d += 2)
238             if (d[1] == 'D')
239               break;
240
241           /* Don't use for printout the variants of most floating
242              point coprocessor instructions which use the same
243              register number in two places, as above. */
244           if (*d == 0)
245             for (d = opc->args; *d; d += 2)
246               if (d[1] == 't')
247                 break;
248
249           if (*d == 0 && match > bestmask)
250             {
251               best = opc;
252               bestmask = match;
253             }
254         }
255     }
256
257   if (best == 0)
258     goto invalid;
259
260   /* Point at first word of argument data,
261      and at descriptor for first argument.  */
262   p = buffer + 2;
263   
264   /* Figure out how long the fixed-size portion of the instruction is.
265      The only place this is stored in the opcode table is
266      in the arguments--look for arguments which specify fields in the 2nd
267      or 3rd words of the instruction.  */
268   for (d = best->args; *d; d += 2)
269     {
270       /* I don't think it is necessary to be checking d[0] here; I suspect
271          all this could be moved to the case statement below.  */
272       if (d[0] == '#')
273         {
274           if (d[1] == 'l' && p - buffer < 6)
275             p = buffer + 6;
276           else if (p - buffer < 4 && d[1] != 'C' && d[1] != '8' )
277             p = buffer + 4;
278         }
279       if ((d[0] == 'L' || d[0] == 'l') && d[1] == 'w' && p - buffer < 4)
280         p = buffer + 4;
281       switch (d[1])
282         {
283         case '1':
284         case '2':
285         case '3':
286         case '7':
287         case '8':
288         case '9':
289         case 'i':
290           if (p - buffer < 4)
291             p = buffer + 4;
292           break;
293         case '4':
294         case '5':
295         case '6':
296           if (p - buffer < 6)
297             p = buffer + 6;
298           break;
299         default:
300           break;
301         }
302     }
303   /* pflusha is an exception; it takes no arguments but is two words long.  */
304   if (buffer[0] == 0xf0 && buffer[1] == 0 && buffer[2] == 0x24 &&
305       buffer[3] == 0)
306     p = buffer + 4;
307   
308   FETCH_DATA (info, p);
309   
310   d = best->args;
311
312   /* We can the operands twice.  The first time we don't print anything,
313      but look for errors. */
314
315   save_p = p;
316   info->print_address_func = dummy_print_address;
317   info->fprintf_func = (fprintf_ftype)dummy_printer;
318   for ( ; *d; d += 2)
319     {
320       int eaten = print_insn_arg (d, buffer, p, memaddr + p - buffer, info);
321       if (eaten >= 0)
322         p += eaten;
323       else if (eaten == -1)
324         goto invalid;
325       else
326         {
327           (*info->fprintf_func)(info->stream,
328                                 "<internal error in opcode table: %s %s>\n",
329                                 best->name,
330                                 best->args);
331           goto invalid;
332         }
333
334     }
335   p = save_p;
336   info->fprintf_func = save_printer;
337   info->print_address_func = save_print_address;
338
339   d = best->args;
340
341   (*info->fprintf_func) (info->stream, "%s", best->name);
342
343   if (*d)
344     (*info->fprintf_func) (info->stream, " ");
345
346   while (*d)
347     {
348       p += print_insn_arg (d, buffer, p, memaddr + p - buffer, info);
349       d += 2;
350       if (*d && *(d - 2) != 'I' && *d != 'k')
351         (*info->fprintf_func) (info->stream, ",");
352     }
353   return p - buffer;
354
355  invalid:
356   /* Handle undefined instructions.  */
357   info->fprintf_func = save_printer;
358   info->print_address_func = save_print_address;
359   (*info->fprintf_func) (info->stream, "0%o",
360                          (buffer[0] << 8) + buffer[1]);
361   return 2;
362 }
363
364 /* Returns number of bytes "eaten" by the operand, or
365    return -1 if an invalid operand was found, or -2 if
366    an opcode tabe error was found. */
367
368 static int
369 print_insn_arg (d, buffer, p0, addr, info)
370      char *d;
371      unsigned char *buffer;
372      unsigned char *p0;
373      bfd_vma addr;              /* PC for this arg to be relative to */
374      disassemble_info *info;
375 {
376   register int val = 0;
377   register int place = d[1];
378   register unsigned char *p = p0;
379   int regno;
380   register CONST char *regname;
381   register unsigned char *p1;
382   double flval;
383   int flt_p;
384
385   switch (*d)
386     {
387     case 'c':           /* cache identifier */
388       {
389         static char *cacheFieldName[] = { "NOP", "dc", "ic", "bc" };
390         val = fetch_arg (buffer, place, 2, info);
391         (*info->fprintf_func) (info->stream, cacheFieldName[val]);
392         break;
393       }
394
395     case 'a':           /* address register indirect only. Cf. case '+'. */
396       {
397         (*info->fprintf_func)
398           (info->stream,
399            "%s@",
400            reg_names [fetch_arg (buffer, place, 3, info) + 8]);
401         break;
402       }
403
404     case '_':           /* 32-bit absolute address for move16. */
405       {
406         val = NEXTLONG (p);
407         (*info->fprintf_func) (info->stream, "@#");
408         (*info->print_address_func) (val, info);
409         break;
410       }
411
412     case 'C':
413       (*info->fprintf_func) (info->stream, "ccr");
414       break;
415
416     case 'S':
417       (*info->fprintf_func) (info->stream, "sr");
418       break;
419
420     case 'U':
421       (*info->fprintf_func) (info->stream, "usp");
422       break;
423
424     case 'J':
425       {
426         static struct { char *name; int value; } names[]
427           = {{"sfc", 0x000}, {"dfc", 0x001}, {"cacr", 0x002},
428              {"tc",  0x003}, {"itt0",0x004}, {"itt1", 0x005},
429              {"dtt0",0x006}, {"dtt1",0x007}, {"buscr",0x008},
430              {"usp", 0x800}, {"vbr", 0x801}, {"caar", 0x802},
431              {"msp", 0x803}, {"isp", 0x804},
432
433              /* Should we be calling this psr like we do in case 'Y'?  */
434              {"mmusr",0x805},
435
436              {"urp", 0x806}, {"srp", 0x807}, {"pcr", 0x808}};
437
438         val = fetch_arg (buffer, place, 12, info);
439         for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--)
440           if (names[regno].value == val)
441             {
442               (*info->fprintf_func) (info->stream, names[regno].name);
443               break;
444             }
445         if (regno < 0)
446           (*info->fprintf_func) (info->stream, "%d", val);
447       }
448       break;
449
450     case 'Q':
451       val = fetch_arg (buffer, place, 3, info);
452       /* 0 means 8, except for the bkpt instruction... */
453       if (val == 0 && d[1] != 's')
454         val = 8;
455       (*info->fprintf_func) (info->stream, "#%d", val);
456       break;
457
458     case 'M':
459       val = fetch_arg (buffer, place, 8, info);
460       if (val & 0x80)
461         val = val - 0x100;
462       (*info->fprintf_func) (info->stream, "#%d", val);
463       break;
464
465     case 'T':
466       val = fetch_arg (buffer, place, 4, info);
467       (*info->fprintf_func) (info->stream, "#%d", val);
468       break;
469
470     case 'D':
471       (*info->fprintf_func) (info->stream, "%s",
472                              reg_names[fetch_arg (buffer, place, 3, info)]);
473       break;
474
475     case 'A':
476       (*info->fprintf_func)
477         (info->stream, "%s",
478          reg_names[fetch_arg (buffer, place, 3, info) + 010]);
479       break;
480
481     case 'R':
482       (*info->fprintf_func)
483         (info->stream, "%s",
484          reg_names[fetch_arg (buffer, place, 4, info)]);
485       break;
486
487     case 'r':
488       (*info->fprintf_func)
489         (info->stream, "%s@",
490          reg_names[fetch_arg (buffer, place, 4, info)]);
491       break;
492
493     case 'F':
494       (*info->fprintf_func)
495         (info->stream, "fp%d",
496          fetch_arg (buffer, place, 3, info));
497       break;
498
499     case 'O':
500       val = fetch_arg (buffer, place, 6, info);
501       if (val & 0x20)
502         (*info->fprintf_func) (info->stream, "%s", reg_names [val & 7]);
503       else
504         (*info->fprintf_func) (info->stream, "%d", val);
505       break;
506
507     case '+':
508       (*info->fprintf_func)
509         (info->stream, "%s@+",
510          reg_names[fetch_arg (buffer, place, 3, info) + 8]);
511       break;
512
513     case '-':
514       (*info->fprintf_func)
515         (info->stream, "%s@-",
516          reg_names[fetch_arg (buffer, place, 3, info) + 8]);
517       break;
518
519     case 'k':
520       if (place == 'k')
521         (*info->fprintf_func)
522           (info->stream, "{%s}",
523            reg_names[fetch_arg (buffer, place, 3, info)]);
524       else if (place == 'C')
525         {
526           val = fetch_arg (buffer, place, 7, info);
527           if ( val > 63 )               /* This is a signed constant. */
528             val -= 128;
529           (*info->fprintf_func) (info->stream, "{#%d}", val);
530         }
531       else
532         return -2;
533       break;
534
535     case '#':
536     case '^':
537       p1 = buffer + (*d == '#' ? 2 : 4);
538       if (place == 's')
539         val = fetch_arg (buffer, place, 4, info);
540       else if (place == 'C')
541         val = fetch_arg (buffer, place, 7, info);
542       else if (place == '8')
543         val = fetch_arg (buffer, place, 3, info);
544       else if (place == '3')
545         val = fetch_arg (buffer, place, 8, info);
546       else if (place == 'b')
547         val = NEXTBYTE (p1);
548       else if (place == 'w')
549         val = NEXTWORD (p1);
550       else if (place == 'l')
551         val = NEXTLONG (p1);
552       else
553         return -2;
554       (*info->fprintf_func) (info->stream, "#%d", val);
555       break;
556
557     case 'B':
558       if (place == 'b')
559         val = NEXTBYTE (p);
560       else if (place == 'B')
561         val = COERCE_SIGNED_CHAR(buffer[1]);
562       else if (place == 'w' || place == 'W')
563         val = NEXTWORD (p);
564       else if (place == 'l' || place == 'L')
565         val = NEXTLONG (p);
566       else if (place == 'g')
567         {
568           val = NEXTBYTE (buffer);
569           if (val == 0)
570             val = NEXTWORD (p);
571           else if (val == -1)
572             val = NEXTLONG (p);
573         }
574       else if (place == 'c')
575         {
576           if (buffer[1] & 0x40)         /* If bit six is one, long offset */
577             val = NEXTLONG (p);
578           else
579             val = NEXTWORD (p);
580         }
581       else
582         return -2;
583
584       (*info->print_address_func) (addr + val, info);
585       break;
586
587     case 'd':
588       val = NEXTWORD (p);
589       (*info->fprintf_func)
590         (info->stream, "%s@(%d)",
591          reg_names[fetch_arg (buffer, place, 3, info)], val);
592       break;
593
594     case 's':
595       (*info->fprintf_func) (info->stream, "%s",
596                              fpcr_names[fetch_arg (buffer, place, 3, info)]);
597       break;
598
599     case 'I':
600       /* Get coprocessor ID... */
601       val = fetch_arg (buffer, 'd', 3, info);
602       
603       if (val != 1)                             /* Unusual coprocessor ID? */
604         (*info->fprintf_func) (info->stream, "(cpid=%d) ", val);
605       break;
606
607     case '*':
608     case '~':
609     case '%':
610     case ';':
611     case '@':
612     case '!':
613     case '$':
614     case '?':
615     case '/':
616     case '&':
617     case '`':
618     case '|':
619
620       if (place == 'd')
621         {
622           val = fetch_arg (buffer, 'x', 6, info);
623           val = ((val & 7) << 3) + ((val >> 3) & 7);
624         }
625       else
626         val = fetch_arg (buffer, 's', 6, info);
627
628       /* Get register number assuming address register.  */
629       regno = (val & 7) + 8;
630       regname = reg_names[regno];
631       switch (val >> 3)
632         {
633         case 0:
634           (*info->fprintf_func) (info->stream, "%s", reg_names[val]);
635           break;
636
637         case 1:
638           (*info->fprintf_func) (info->stream, "%s", regname);
639           break;
640
641         case 2:
642           (*info->fprintf_func) (info->stream, "%s@", regname);
643           break;
644
645         case 3:
646           (*info->fprintf_func) (info->stream, "%s@+", regname);
647           break;
648
649         case 4:
650           (*info->fprintf_func) (info->stream, "%s@-", regname);
651           break;
652
653         case 5:
654           val = NEXTWORD (p);
655           (*info->fprintf_func) (info->stream, "%s@(%d)", regname, val);
656           break;
657
658         case 6:
659           p = print_indexed (regno, p, addr, info);
660           break;
661
662         case 7:
663           switch (val & 7)
664             {
665             case 0:
666               val = NEXTWORD (p);
667               (*info->fprintf_func) (info->stream, "@#");
668               (*info->print_address_func) (val, info);
669               break;
670
671             case 1:
672               val = NEXTLONG (p);
673               (*info->fprintf_func) (info->stream, "@#");
674               (*info->print_address_func) (val, info);
675               break;
676
677             case 2:
678               val = NEXTWORD (p);
679               (*info->print_address_func) (addr + val, info);
680               break;
681
682             case 3:
683               p = print_indexed (-1, p, addr, info);
684               break;
685
686             case 4:
687               flt_p = 1;        /* Assume it's a float... */
688               switch( place )
689               {
690                 case 'b':
691                   val = NEXTBYTE (p);
692                   flt_p = 0;
693                   break;
694
695                 case 'w':
696                   val = NEXTWORD (p);
697                   flt_p = 0;
698                   break;
699
700                 case 'l':
701                   val = NEXTLONG (p);
702                   flt_p = 0;
703                   break;
704
705                 case 'f':
706                   NEXTSINGLE(flval, p);
707                   break;
708
709                 case 'F':
710                   NEXTDOUBLE(flval, p);
711                   break;
712
713                 case 'x':
714                   FETCH_DATA (info, p + 12);
715                   floatformat_to_double (&floatformat_m68881_ext,
716                                          (char *) p, &flval);
717                   p += 12;
718                   break;
719
720                 case 'p':
721                   flval = NEXTPACKED(p);
722                   break;
723
724                 default:
725                   return -1;
726               }
727               if ( flt_p )      /* Print a float? */
728                 (*info->fprintf_func) (info->stream, "#%g", flval);
729               else
730                 (*info->fprintf_func) (info->stream, "#%d", val);
731               break;
732
733             default:
734               return -1;
735             }
736         }
737       break;
738
739     case 'L':
740     case 'l':
741         if (place == 'w')
742           {
743             char doneany;
744             p1 = buffer + 2;
745             val = NEXTWORD (p1);
746             /* Move the pointer ahead if this point is farther ahead
747                than the last.  */
748             p = p1 > p ? p1 : p;
749             if (val == 0)
750               {
751                 (*info->fprintf_func) (info->stream, "#0");
752                 break;
753               }
754             if (*d == 'l')
755               {
756                 register int newval = 0;
757                 for (regno = 0; regno < 16; ++regno)
758                   if (val & (0x8000 >> regno))
759                     newval |= 1 << regno;
760                 val = newval;
761               }
762             val &= 0xffff;
763             doneany = 0;
764             for (regno = 0; regno < 16; ++regno)
765               if (val & (1 << regno))
766                 {
767                   int first_regno;
768                   if (doneany)
769                     (*info->fprintf_func) (info->stream, "/");
770                   doneany = 1;
771                   (*info->fprintf_func) (info->stream, "%s", reg_names[regno]);
772                   first_regno = regno;
773                   while (val & (1 << (regno + 1)))
774                     ++regno;
775                   if (regno > first_regno)
776                     (*info->fprintf_func) (info->stream, "-%s",
777                                            reg_names[regno]);
778                 }
779           }
780         else if (place == '3')
781           {
782             /* `fmovem' insn.  */
783             char doneany;
784             val = fetch_arg (buffer, place, 8, info);
785             if (val == 0)
786               {
787                 (*info->fprintf_func) (info->stream, "#0");
788                 break;
789               }
790             if (*d == 'l')
791               {
792                 register int newval = 0;
793                 for (regno = 0; regno < 8; ++regno)
794                   if (val & (0x80 >> regno))
795                     newval |= 1 << regno;
796                 val = newval;
797               }
798             val &= 0xff;
799             doneany = 0;
800             for (regno = 0; regno < 8; ++regno)
801               if (val & (1 << regno))
802                 {
803                   int first_regno;
804                   if (doneany)
805                     (*info->fprintf_func) (info->stream, "/");
806                   doneany = 1;
807                   (*info->fprintf_func) (info->stream, "fp%d", regno);
808                   first_regno = regno;
809                   while (val & (1 << (regno + 1)))
810                     ++regno;
811                   if (regno > first_regno)
812                     (*info->fprintf_func) (info->stream, "-fp%d", regno);
813                 }
814           }
815         else
816           return -2;
817       break;
818
819     case 'X':
820       place = '8';
821     case 'Y':
822     case 'Z':
823     case 'W':
824     case '3':
825     case 'P':
826       {
827         int val = fetch_arg (buffer, place, 5, info);
828         char *name = 0;
829         switch (val)
830           {
831           case 2: name = "tt0"; break;
832           case 3: name = "tt1"; break;
833           case 0x10: name = "tc"; break;
834           case 0x11: name = "drp"; break;
835           case 0x12: name = "srp"; break;
836           case 0x13: name = "crp"; break;
837           case 0x14: name = "cal"; break;
838           case 0x15: name = "val"; break;
839           case 0x16: name = "scc"; break;
840           case 0x17: name = "ac"; break;
841           case 0x18: name = "psr"; break;
842           case 0x19: name = "pcsr"; break;
843           case 0x1c:
844           case 0x1d:
845             {
846               int break_reg = ((buffer[3] >> 2) & 7);
847               (*info->fprintf_func)
848                 (info->stream, val == 0x1c ? "bad%d" : "bac%d",
849                  break_reg);
850             }
851             break;
852           default:
853             (*info->fprintf_func) (info->stream, "<mmu register %d>", val);
854           }
855         if (name)
856           (*info->fprintf_func) (info->stream, name);
857       }
858       break;
859
860     case 'f':
861       {
862         int fc = fetch_arg (buffer, place, 5, info);
863         if (fc == 1)
864           (*info->fprintf_func) (info->stream, "dfc");
865         else if (fc == 0)
866           (*info->fprintf_func) (info->stream, "sfc");
867         else
868           (*info->fprintf_func) (info->stream, "<function code %d>", fc);
869       }
870       break;
871
872     case 'V':
873       (*info->fprintf_func) (info->stream, "val");
874       break;
875
876     case 't':
877       {
878         int level = fetch_arg (buffer, place, 3, info);
879         (*info->fprintf_func) (info->stream, "%d", level);
880       }
881       break;
882
883     default:
884       return -2;
885     }
886
887   return p - p0;
888 }
889
890 /* Fetch BITS bits from a position in the instruction specified by CODE.
891    CODE is a "place to put an argument", or 'x' for a destination
892    that is a general address (mode and register).
893    BUFFER contains the instruction.  */
894
895 static int
896 fetch_arg (buffer, code, bits, info)
897      unsigned char *buffer;
898      int code;
899      int bits;
900      disassemble_info *info;
901 {
902   register int val = 0;
903   switch (code)
904     {
905     case 's':
906       val = buffer[1];
907       break;
908
909     case 'd':                   /* Destination, for register or quick.  */
910       val = (buffer[0] << 8) + buffer[1];
911       val >>= 9;
912       break;
913
914     case 'x':                   /* Destination, for general arg */
915       val = (buffer[0] << 8) + buffer[1];
916       val >>= 6;
917       break;
918
919     case 'k':
920       FETCH_DATA (info, buffer + 3);
921       val = (buffer[3] >> 4);
922       break;
923
924     case 'C':
925       FETCH_DATA (info, buffer + 3);
926       val = buffer[3];
927       break;
928
929     case '1':
930       FETCH_DATA (info, buffer + 3);
931       val = (buffer[2] << 8) + buffer[3];
932       val >>= 12;
933       break;
934
935     case '2':
936       FETCH_DATA (info, buffer + 3);
937       val = (buffer[2] << 8) + buffer[3];
938       val >>= 6;
939       break;
940
941     case '3':
942     case 'j':
943       FETCH_DATA (info, buffer + 3);
944       val = (buffer[2] << 8) + buffer[3];
945       break;
946
947     case '4':
948       FETCH_DATA (info, buffer + 5);
949       val = (buffer[4] << 8) + buffer[5];
950       val >>= 12;
951       break;
952
953     case '5':
954       FETCH_DATA (info, buffer + 5);
955       val = (buffer[4] << 8) + buffer[5];
956       val >>= 6;
957       break;
958
959     case '6':
960       FETCH_DATA (info, buffer + 5);
961       val = (buffer[4] << 8) + buffer[5];
962       break;
963
964     case '7':
965       FETCH_DATA (info, buffer + 3);
966       val = (buffer[2] << 8) + buffer[3];
967       val >>= 7;
968       break;
969       
970     case '8':
971       FETCH_DATA (info, buffer + 3);
972       val = (buffer[2] << 8) + buffer[3];
973       val >>= 10;
974       break;
975
976     case '9':
977       FETCH_DATA (info, buffer + 3);
978       val = (buffer[2] << 8) + buffer[3];
979       val >>= 5;
980       break;
981
982     case 'e':
983       val = (buffer[1] >> 6);
984       break;
985
986     default:
987       abort ();
988     }
989
990   switch (bits)
991     {
992     case 2:
993       return val & 3;
994     case 3:
995       return val & 7;
996     case 4:
997       return val & 017;
998     case 5:
999       return val & 037;
1000     case 6:
1001       return val & 077;
1002     case 7:
1003       return val & 0177;
1004     case 8:
1005       return val & 0377;
1006     case 12:
1007       return val & 07777;
1008     default:
1009       abort ();
1010     }
1011 }
1012
1013 /* Print an indexed argument.  The base register is BASEREG (-1 for pc).
1014    P points to extension word, in buffer.
1015    ADDR is the nominal core address of that extension word.  */
1016
1017 static unsigned char *
1018 print_indexed (basereg, p, addr, info)
1019      int basereg;
1020      unsigned char *p;
1021      bfd_vma addr;
1022      disassemble_info *info;
1023 {
1024   register int word;
1025   static char *scales[] = {"", "*2", "*4", "*8"};
1026   register int base_disp;
1027   register int outer_disp;
1028   char buf[40];
1029
1030   word = NEXTWORD (p);
1031
1032   /* Generate the text for the index register.
1033      Where this will be output is not yet determined.  */
1034   sprintf (buf, "[%s.%c%s]",
1035            reg_names[(word >> 12) & 0xf],
1036            (word & 0x800) ? 'l' : 'w',
1037            scales[(word >> 9) & 3]);
1038
1039   /* Handle the 68000 style of indexing.  */
1040
1041   if ((word & 0x100) == 0)
1042     {
1043       print_base (basereg,
1044                   ((word & 0x80) ? word | 0xff00 : word & 0xff)
1045                   + ((basereg == -1) ? addr : 0),
1046                   info);
1047       (*info->fprintf_func) (info->stream, "%s", buf);
1048       return p;
1049     }
1050
1051   /* Handle the generalized kind.  */
1052   /* First, compute the displacement to add to the base register.  */
1053
1054   if (word & 0200)
1055     basereg = -2;
1056   if (word & 0100)
1057     buf[0] = 0;
1058   base_disp = 0;
1059   switch ((word >> 4) & 3)
1060     {
1061     case 2:
1062       base_disp = NEXTWORD (p);
1063       break;
1064     case 3:
1065       base_disp = NEXTLONG (p);
1066     }
1067   if (basereg == -1)
1068     base_disp += addr;
1069
1070   /* Handle single-level case (not indirect) */
1071
1072   if ((word & 7) == 0)
1073     {
1074       print_base (basereg, base_disp, info);
1075       (*info->fprintf_func) (info->stream, "%s", buf);
1076       return p;
1077     }
1078
1079   /* Two level.  Compute displacement to add after indirection.  */
1080
1081   outer_disp = 0;
1082   switch (word & 3)
1083     {
1084     case 2:
1085       outer_disp = NEXTWORD (p);
1086       break;
1087     case 3:
1088       outer_disp = NEXTLONG (p);
1089     }
1090
1091   (*info->fprintf_func) (info->stream, "%d(", outer_disp);
1092   print_base (basereg, base_disp, info);
1093
1094   /* If postindexed, print the closeparen before the index.  */
1095   if (word & 4)
1096     (*info->fprintf_func) (info->stream, ")%s", buf);
1097   /* If preindexed, print the closeparen after the index.  */
1098   else
1099     (*info->fprintf_func) (info->stream, "%s)", buf);
1100
1101   return p;
1102 }
1103
1104 /* Print a base register REGNO and displacement DISP, on INFO->STREAM.
1105    REGNO = -1 for pc, -2 for none (suppressed).  */
1106
1107 static void
1108 print_base (regno, disp, info)
1109      int regno;
1110      int disp;
1111      disassemble_info *info;
1112 {
1113   if (regno == -2)
1114     (*info->fprintf_func) (info->stream, "%d", disp);
1115   else if (regno == -1)
1116     (*info->fprintf_func) (info->stream, "0x%x", (unsigned) disp);
1117   else
1118     (*info->fprintf_func) (info->stream, "%d(%s)", disp, reg_names[regno]);
1119 }