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