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