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