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