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