OSDN Git Service

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