1 /* Print Motorola 68k instructions.
2    Copyright (C) 1986-2024 Free Software Foundation, Inc.
3 
4    This file is part of the GNU opcodes library.
5 
6    This library is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3, or (at your option)
9    any later version.
10 
11    It is distributed in the hope that it will be useful, but WITHOUT
12    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14    License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19    MA 02110-1301, USA.  */
20 
21 #include "sysdep.h"
22 #include "disassemble.h"
23 #include "floatformat.h"
24 #include "libiberty.h"
25 #include "opintl.h"
26 #include "cpu-m68k.h"
27 #include "opcode/m68k.h"
28 
29 /* Local function prototypes.  */
30 
31 const char * const fpcr_names[] =
32 {
33   "", "%fpiar", "%fpsr", "%fpiar/%fpsr", "%fpcr",
34   "%fpiar/%fpcr", "%fpsr/%fpcr", "%fpiar/%fpsr/%fpcr"
35 };
36 
37 static char *const reg_names[] =
38 {
39   "%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7",
40   "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%fp", "%sp",
41   "%ps", "%pc"
42 };
43 
44 /* Name of register halves for MAC/EMAC.
45    Seperate from reg_names since 'spu', 'fpl' look weird.  */
46 static char *const reg_half_names[] =
47 {
48   "%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7",
49   "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%a6", "%a7",
50   "%ps", "%pc"
51 };
52 
53 /* Sign-extend an (unsigned char).  */
54 #if __STDC__ == 1
55 #define COERCE_SIGNED_CHAR(ch) ((signed char) (ch))
56 #else
57 #define COERCE_SIGNED_CHAR(ch) ((int) (((ch) ^ 0x80) & 0xFF) - 128)
58 #endif
59 
60 /* Error code of print_insn_arg's return value.  */
61 
62 enum print_insn_arg_error
63   {
64     /* An invalid operand is found.  */
65     PRINT_INSN_ARG_INVALID_OPERAND = -1,
66 
67     /* An opcode table error.  */
68     PRINT_INSN_ARG_INVALID_OP_TABLE = -2,
69 
70     /* A memory error.  */
71     PRINT_INSN_ARG_MEMORY_ERROR = -3,
72   };
73 
74 /* Get a 1 byte signed integer.  */
75 #define NEXTBYTE(p, val)                          \
76   do                                                        \
77     {                                                       \
78       p += 2;                                               \
79       if (!FETCH_DATA (info, p))                  \
80           return PRINT_INSN_ARG_MEMORY_ERROR;     \
81       val = COERCE_SIGNED_CHAR (p[-1]);           \
82     }                                                       \
83   while (0)
84 
85 /* Get a 2 byte signed integer.  */
86 #define COERCE16(x) ((int) (((x) ^ 0x8000) - 0x8000))
87 
88 #define NEXTWORD(p, val, ret_val)                 \
89   do                                                        \
90     {                                                       \
91       p += 2;                                               \
92       if (!FETCH_DATA (info, p))                  \
93           return ret_val;                                   \
94       val = COERCE16 ((p[-2] << 8) + p[-1]);      \
95     }                                                       \
96   while (0)
97 
98 /* Get a 4 byte signed integer.  */
99 #define COERCE32(x) (((bfd_vma) (x) ^ 0x80000000) - 0x80000000)
100 
101 #define NEXTLONG(p, val, ret_val)                                               \
102   do                                                                                      \
103     {                                                                                     \
104       p += 4;                                                                             \
105       if (!FETCH_DATA (info, p))                                                \
106           return ret_val;                                                                 \
107       val = COERCE32 (((((((unsigned) p[-4] << 8) + p[-3]) << 8)      \
108                               + p[-2]) << 8) + p[-1]);                          \
109     }                                                                                     \
110   while (0)
111 
112 /* Get a 4 byte unsigned integer.  */
113 #define NEXTULONG(p, val)                                                       \
114   do                                                                                      \
115     {                                                                                     \
116       p += 4;                                                                             \
117       if (!FETCH_DATA (info, p))                                                \
118           return PRINT_INSN_ARG_MEMORY_ERROR;                                   \
119       val = (((((((unsigned) p[-4] << 8) + p[-3]) << 8)                         \
120                  + p[-2]) << 8) + p[-1]);                                                 \
121     }                                                                                     \
122   while (0)
123 
124 /* Get a single precision float.  */
125 #define NEXTSINGLE(val, p)                                            \
126   do                                                                            \
127     {                                                                           \
128       p += 4;                                                                   \
129       if (!FETCH_DATA (info, p))                                      \
130           return PRINT_INSN_ARG_MEMORY_ERROR;                         \
131       floatformat_to_double (& floatformat_ieee_single_big, \
132                                    (char *) p - 4, & val);            \
133     }                                                                           \
134   while (0)
135 
136 /* Get a double precision float.  */
137 #define NEXTDOUBLE(val, p)                                            \
138   do                                                                            \
139     {                                                                           \
140       p += 8;                                                                   \
141       if (!FETCH_DATA (info, p))                                      \
142           return PRINT_INSN_ARG_MEMORY_ERROR;                         \
143       floatformat_to_double (& floatformat_ieee_double_big, \
144                                    (char *) p - 8, & val);            \
145     }                                                                           \
146   while (0)
147 
148 /* Get an extended precision float.  */
149 #define NEXTEXTEND(val, p)                                  \
150   do                                                                  \
151     {                                                                 \
152       p += 12;                                                        \
153       if (!FETCH_DATA (info, p))                            \
154           return PRINT_INSN_ARG_MEMORY_ERROR;               \
155       floatformat_to_double (& floatformat_m68881_ext,      \
156                                    (char *) p - 12, & val); \
157     }                                                                 \
158   while (0)
159 
160 /* Need a function to convert from packed to double
161    precision.   Actually, it's easier to print a
162    packed number than a double anyway, so maybe
163    there should be a special case to handle this... */
164 #define NEXTPACKED(p, val)                        \
165   do                                                        \
166     {                                                       \
167       p += 12;                                              \
168       if (!FETCH_DATA (info, p))                  \
169           return PRINT_INSN_ARG_MEMORY_ERROR;     \
170       val = 0.0;                                  \
171     }                                                       \
172   while (0)
173 
174 
175 /* Maximum length of an instruction.  */
176 #define MAXLEN 22
177 
178 struct private
179 {
180   /* Points to first byte not fetched.  */
181   bfd_byte *max_fetched;
182   bfd_byte the_buffer[MAXLEN];
183   bfd_vma insn_start;
184 };
185 
186 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
187    to ADDR (exclusive) are valid.  Returns 1 for success, 0 on memory
188    error.  */
189 #define FETCH_DATA(info, addr) \
190   ((addr) <= ((struct private *) (info->private_data))->max_fetched \
191    ? 1 : fetch_data ((info), (addr)))
192 
193 static int
fetch_data(struct disassemble_info * info,bfd_byte * addr)194 fetch_data (struct disassemble_info *info, bfd_byte *addr)
195 {
196   int status;
197   struct private *priv = (struct private *)info->private_data;
198   bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
199 
200   status = (*info->read_memory_func) (start,
201                                               priv->max_fetched,
202                                               addr - priv->max_fetched,
203                                               info);
204   if (status != 0)
205     {
206       (*info->memory_error_func) (status, start, info);
207       return 0;
208     }
209   else
210     priv->max_fetched = addr;
211   return 1;
212 }
213 
214 /* This function is used to print to the bit-bucket.  */
215 static int
dummy_printer(void * file ATTRIBUTE_UNUSED,enum disassembler_style style ATTRIBUTE_UNUSED,const char * format ATTRIBUTE_UNUSED,...)216 dummy_printer (void *file ATTRIBUTE_UNUSED,
217                  enum disassembler_style style ATTRIBUTE_UNUSED,
218                  const char *format ATTRIBUTE_UNUSED,
219                  ...)
220 {
221   return 0;
222 }
223 
224 static void
dummy_print_address(bfd_vma vma ATTRIBUTE_UNUSED,struct disassemble_info * info ATTRIBUTE_UNUSED)225 dummy_print_address (bfd_vma vma ATTRIBUTE_UNUSED,
226                          struct disassemble_info *info ATTRIBUTE_UNUSED)
227 {
228 }
229 
230 /* Fetch BITS bits from a position in the instruction specified by CODE.
231    CODE is a "place to put an argument", or 'x' for a destination
232    that is a general address (mode and register).
233    BUFFER contains the instruction.
234    Returns -1 on failure.  */
235 
236 static int
fetch_arg(unsigned char * buffer,int code,int bits,disassemble_info * info)237 fetch_arg (unsigned char *buffer,
238              int code,
239              int bits,
240              disassemble_info *info)
241 {
242   int val = 0;
243 
244   switch (code)
245     {
246     case '/': /* MAC/EMAC mask bit.  */
247       val = buffer[3] >> 5;
248       break;
249 
250     case 'G': /* EMAC ACC load.  */
251       val = ((buffer[3] >> 3) & 0x2) | ((~buffer[1] >> 7) & 0x1);
252       break;
253 
254     case 'H': /* EMAC ACC !load.  */
255       val = ((buffer[3] >> 3) & 0x2) | ((buffer[1] >> 7) & 0x1);
256       break;
257 
258     case ']': /* EMAC ACCEXT bit.  */
259       val = buffer[0] >> 2;
260       break;
261 
262     case 'I': /* MAC/EMAC scale factor.  */
263       val = buffer[2] >> 1;
264       break;
265 
266     case 'F': /* EMAC ACCx.  */
267       val = buffer[0] >> 1;
268       break;
269 
270     case 'f':
271       val = buffer[1];
272       break;
273 
274     case 's':
275       val = buffer[1];
276       break;
277 
278     case 'd':                           /* Destination, for register or quick.  */
279       val = (buffer[0] << 8) + buffer[1];
280       val >>= 9;
281       break;
282 
283     case 'x':                           /* Destination, for general arg.  */
284       val = (buffer[0] << 8) + buffer[1];
285       val >>= 6;
286       break;
287 
288     case 'k':
289       if (! FETCH_DATA (info, buffer + 3))
290           return -1;
291       val = (buffer[3] >> 4);
292       break;
293 
294     case 'C':
295       if (! FETCH_DATA (info, buffer + 3))
296           return -1;
297       val = buffer[3];
298       break;
299 
300     case '1':
301       if (! FETCH_DATA (info, buffer + 3))
302           return -1;
303       val = (buffer[2] << 8) + buffer[3];
304       val >>= 12;
305       break;
306 
307     case '2':
308       if (! FETCH_DATA (info, buffer + 3))
309           return -1;
310       val = (buffer[2] << 8) + buffer[3];
311       val >>= 6;
312       break;
313 
314     case '3':
315     case 'j':
316       if (! FETCH_DATA (info, buffer + 3))
317           return -1;
318       val = (buffer[2] << 8) + buffer[3];
319       break;
320 
321     case '4':
322       if (! FETCH_DATA (info, buffer + 5))
323           return -1;
324       val = (buffer[4] << 8) + buffer[5];
325       val >>= 12;
326       break;
327 
328     case '5':
329       if (! FETCH_DATA (info, buffer + 5))
330           return -1;
331       val = (buffer[4] << 8) + buffer[5];
332       val >>= 6;
333       break;
334 
335     case '6':
336       if (! FETCH_DATA (info, buffer + 5))
337           return -1;
338       val = (buffer[4] << 8) + buffer[5];
339       break;
340 
341     case '7':
342       if (! FETCH_DATA (info, buffer + 3))
343           return -1;
344       val = (buffer[2] << 8) + buffer[3];
345       val >>= 7;
346       break;
347 
348     case '8':
349       if (! FETCH_DATA (info, buffer + 3))
350           return -1;
351       val = (buffer[2] << 8) + buffer[3];
352       val >>= 10;
353       break;
354 
355     case '9':
356       if (! FETCH_DATA (info, buffer + 3))
357           return -1;
358       val = (buffer[2] << 8) + buffer[3];
359       val >>= 5;
360       break;
361 
362     case 'e':
363       val = (buffer[1] >> 6);
364       break;
365 
366     case 'E':
367       if (! FETCH_DATA (info, buffer + 3))
368           return -1;
369       val = (buffer[2] >> 1);
370       break;
371 
372     case 'm':
373       val = (buffer[1] & 0x40 ? 0x8 : 0)
374           | ((buffer[0] >> 1) & 0x7)
375           | (buffer[3] & 0x80 ? 0x10 : 0);
376       break;
377 
378     case 'n':
379       val = (buffer[1] & 0x40 ? 0x8 : 0) | ((buffer[0] >> 1) & 0x7);
380       break;
381 
382     case 'o':
383       val = (buffer[2] >> 4) | (buffer[3] & 0x80 ? 0x10 : 0);
384       break;
385 
386     case 'M':
387       val = (buffer[1] & 0xf) | (buffer[3] & 0x40 ? 0x10 : 0);
388       break;
389 
390     case 'N':
391       val = (buffer[3] & 0xf) | (buffer[3] & 0x40 ? 0x10 : 0);
392       break;
393 
394     case 'h':
395       val = buffer[2] >> 2;
396       break;
397 
398     default:
399       abort ();
400     }
401 
402   /* bits is never too big.  */
403   return val & ((1 << bits) - 1);
404 }
405 
406 /* Check if an EA is valid for a particular code.  This is required
407    for the EMAC instructions since the type of source address determines
408    if it is a EMAC-load instruciton if the EA is mode 2-5, otherwise it
409    is a non-load EMAC instruction and the bits mean register Ry.
410    A similar case exists for the movem instructions where the register
411    mask is interpreted differently for different EAs.  */
412 
413 static bool
m68k_valid_ea(char code,int val)414 m68k_valid_ea (char code, int val)
415 {
416   int mode, mask;
417 #define M(n0,n1,n2,n3,n4,n5,n6,n70,n71,n72,n73,n74) \
418   (n0 | n1 << 1 | n2 << 2 | n3 << 3 | n4 << 4 | n5 << 5 | n6 << 6 \
419    | n70 << 7 | n71 << 8 | n72 << 9 | n73 << 10 | n74 << 11)
420 
421   switch (code)
422     {
423     case '*':
424       mask = M (1,1,1,1,1,1,1,1,1,1,1,1);
425       break;
426     case '~':
427       mask = M (0,0,1,1,1,1,1,1,1,0,0,0);
428       break;
429     case '%':
430       mask = M (1,1,1,1,1,1,1,1,1,0,0,0);
431       break;
432     case ';':
433       mask = M (1,0,1,1,1,1,1,1,1,1,1,1);
434       break;
435     case '@':
436       mask = M (1,0,1,1,1,1,1,1,1,1,1,0);
437       break;
438     case '!':
439       mask = M (0,0,1,0,0,1,1,1,1,1,1,0);
440       break;
441     case '&':
442       mask = M (0,0,1,0,0,1,1,1,1,0,0,0);
443       break;
444     case '$':
445       mask = M (1,0,1,1,1,1,1,1,1,0,0,0);
446       break;
447     case '?':
448       mask = M (1,0,1,0,0,1,1,1,1,0,0,0);
449       break;
450     case '/':
451       mask = M (1,0,1,0,0,1,1,1,1,1,1,0);
452       break;
453     case '|':
454       mask = M (0,0,1,0,0,1,1,1,1,1,1,0);
455       break;
456     case '>':
457       mask = M (0,0,1,0,1,1,1,1,1,0,0,0);
458       break;
459     case '<':
460       mask = M (0,0,1,1,0,1,1,1,1,1,1,0);
461       break;
462     case 'm':
463       mask = M (1,1,1,1,1,0,0,0,0,0,0,0);
464       break;
465     case 'n':
466       mask = M (0,0,0,0,0,1,0,0,0,1,0,0);
467       break;
468     case 'o':
469       mask = M (0,0,0,0,0,0,1,1,1,0,1,1);
470       break;
471     case 'p':
472       mask = M (1,1,1,1,1,1,0,0,0,0,0,0);
473       break;
474     case 'q':
475       mask = M (1,0,1,1,1,1,0,0,0,0,0,0);
476       break;
477     case 'v':
478       mask = M (1,0,1,1,1,1,0,1,1,0,0,0);
479       break;
480     case 'b':
481       mask = M (1,0,1,1,1,1,0,0,0,1,0,0);
482       break;
483     case 'w':
484       mask = M (0,0,1,1,1,1,0,0,0,1,0,0);
485       break;
486     case 'y':
487       mask = M (0,0,1,0,0,1,0,0,0,0,0,0);
488       break;
489     case 'z':
490       mask = M (0,0,1,0,0,1,0,0,0,1,0,0);
491       break;
492     case '4':
493       mask = M (0,0,1,1,1,1,0,0,0,0,0,0);
494       break;
495     default:
496       abort ();
497     }
498 #undef M
499 
500   mode = (val >> 3) & 7;
501   if (mode == 7)
502     mode += val & 7;
503   return (mask & (1 << mode)) != 0;
504 }
505 
506 /* Print a base register REGNO and displacement DISP, on INFO->STREAM.
507    REGNO = -1 for pc, -2 for none (suppressed).  */
508 
509 static void
print_base(int regno,bfd_vma disp,disassemble_info * info)510 print_base (int regno, bfd_vma disp, disassemble_info *info)
511 {
512   if (regno == -1)
513     {
514       (*info->fprintf_styled_func) (info->stream, dis_style_register, "%%pc");
515       (*info->fprintf_styled_func) (info->stream, dis_style_text, "@(");
516       (*info->print_address_func) (disp, info);
517     }
518   else
519     {
520       if (regno == -3)
521           (*info->fprintf_styled_func) (info->stream, dis_style_register,
522                                               "%%zpc");
523       else if (regno != -2)
524           (*info->fprintf_styled_func) (info->stream, dis_style_register,
525                                               "%s", reg_names[regno]);
526       (*info->fprintf_styled_func) (info->stream, dis_style_text, "@(");
527       (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
528                                             "%" PRIx64, (uint64_t) disp);
529     }
530 }
531 
532 /* Print the index register of an indexed argument, as encoded in the
533    extension word.  */
534 
535 static void
print_index_register(int ext,disassemble_info * info)536 print_index_register (int ext, disassemble_info *info)
537 {
538   (*info->fprintf_styled_func) (info->stream, dis_style_register,
539                                         "%s", reg_names[(ext >> 12) & 0xf]);
540   (*info->fprintf_styled_func) (info->stream, dis_style_text,
541                                         ":%c", ext & 0x800 ? 'l' : 'w');
542   if ((ext >> 9) & 3)
543     {
544       (*info->fprintf_styled_func) (info->stream, dis_style_text, ":");
545       (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
546                                             "%d", 1 << ((ext >> 9) & 3));
547     }
548 }
549 
550 /* Print an indexed argument.  The base register is BASEREG (-1 for pc).
551    P points to extension word, in buffer.
552    ADDR is the nominal core address of that extension word.
553    Returns NULL upon error.  */
554 
555 static unsigned char *
print_indexed(int basereg,unsigned char * p,bfd_vma addr,disassemble_info * info)556 print_indexed (int basereg,
557                  unsigned char *p,
558                  bfd_vma addr,
559                  disassemble_info *info)
560 {
561   int word;
562   bfd_vma base_disp;
563   bfd_vma outer_disp;
564   bool print_index = true;
565 
566   NEXTWORD (p, word, NULL);
567 
568   /* Handle the 68000 style of indexing.  */
569 
570   if ((word & 0x100) == 0)
571     {
572       base_disp = word & 0xff;
573       if ((base_disp & 0x80) != 0)
574           base_disp -= 0x100;
575       if (basereg == -1)
576           base_disp += addr;
577       print_base (basereg, base_disp, info);
578       (*info->fprintf_styled_func) (info->stream, dis_style_text, ",");
579       print_index_register (word, info);
580       (*info->fprintf_styled_func) (info->stream, dis_style_text, ")");
581       return p;
582     }
583 
584   /* Handle the generalized kind.  */
585   /* First, compute the displacement to add to the base register.  */
586   if (word & 0200)
587     {
588       if (basereg == -1)
589           basereg = -3;
590       else
591           basereg = -2;
592     }
593   if (word & 0100)
594     print_index = false;
595   base_disp = 0;
596   switch ((word >> 4) & 3)
597     {
598     case 2:
599       NEXTWORD (p, base_disp, NULL);
600       break;
601     case 3:
602       NEXTLONG (p, base_disp, NULL);
603     }
604   if (basereg == -1)
605     base_disp += addr;
606 
607   /* Handle single-level case (not indirect).  */
608   if ((word & 7) == 0)
609     {
610       print_base (basereg, base_disp, info);
611       if (print_index)
612           {
613             (*info->fprintf_styled_func) (info->stream, dis_style_text, ",");
614             print_index_register (word, info);
615           }
616       (*info->fprintf_styled_func) (info->stream, dis_style_text, ")");
617       return p;
618     }
619 
620   /* Two level.  Compute displacement to add after indirection.  */
621   outer_disp = 0;
622   switch (word & 3)
623     {
624     case 2:
625       NEXTWORD (p, outer_disp, NULL);
626       break;
627     case 3:
628       NEXTLONG (p, outer_disp, NULL);
629     }
630 
631   print_base (basereg, base_disp, info);
632   if ((word & 4) == 0 && print_index)
633     {
634       (*info->fprintf_styled_func) (info->stream, dis_style_text, ",");
635       print_index_register (word, info);
636       print_index = false;
637     }
638   (*info->fprintf_styled_func) (info->stream, dis_style_text,
639                                         ")@(");
640   (*info->fprintf_styled_func) (info->stream, dis_style_address_offset,
641                                         "%" PRIx64, (uint64_t) outer_disp);
642   if (print_index)
643     {
644       (*info->fprintf_styled_func) (info->stream, dis_style_text, ",");
645       print_index_register (word, info);
646     }
647   (*info->fprintf_styled_func) (info->stream, dis_style_text, ")");
648 
649   return p;
650 }
651 
652 #define FETCH_ARG(size, val)                                \
653   do                                                                  \
654     {                                                                 \
655       val = fetch_arg (buffer, place, size, info);          \
656       if (val < 0)                                          \
657           return PRINT_INSN_ARG_MEMORY_ERROR;               \
658     }                                                                 \
659   while (0)
660 
661 /* Returns number of bytes "eaten" by the operand, or
662    return enum print_insn_arg_error.  ADDR is the pc for this arg to be
663    relative to.  */
664 
665 static int
print_insn_arg(const char * d,unsigned char * buffer,unsigned char * p0,bfd_vma addr,disassemble_info * info)666 print_insn_arg (const char *d,
667                     unsigned char *buffer,
668                     unsigned char *p0,
669                     bfd_vma addr,
670                     disassemble_info *info)
671 {
672   int val = 0;
673   int place = d[1];
674   unsigned char *p = p0;
675   int regno;
676   const char *regname;
677   unsigned char *p1;
678   double flval;
679   int flt_p;
680   bfd_signed_vma disp;
681   unsigned int uval;
682 
683   switch (*d)
684     {
685     case 'c':                 /* Cache identifier.  */
686       {
687         static char *const cacheFieldName[] = { "nc", "dc", "ic", "bc" };
688         FETCH_ARG (2, val);
689           (*info->fprintf_styled_func) (info->stream, dis_style_sub_mnemonic,
690                                               "%s", cacheFieldName[val]);
691         break;
692       }
693 
694     case 'a':                 /* Address register indirect only. Cf. case '+'.  */
695       {
696           FETCH_ARG (3, val);
697           (*info->fprintf_styled_func) (info->stream, dis_style_register, "%s",
698                                               reg_names[val + 8]);
699           (*info->fprintf_styled_func) (info->stream, dis_style_text, "@");
700         break;
701       }
702 
703     case '_':                 /* 32-bit absolute address for move16.  */
704       {
705         NEXTULONG (p, uval);
706           (*info->print_address_func) (uval, info);
707         break;
708       }
709 
710     case 'C':
711       (*info->fprintf_styled_func) (info->stream, dis_style_register, "%%ccr");
712       break;
713 
714     case 'S':
715       (*info->fprintf_styled_func) (info->stream, dis_style_register, "%%sr");
716       break;
717 
718     case 'U':
719       (*info->fprintf_styled_func) (info->stream, dis_style_register, "%%usp");
720       break;
721 
722     case 'E':
723       (*info->fprintf_styled_func) (info->stream, dis_style_register, "%%acc");
724       break;
725 
726     case 'G':
727       (*info->fprintf_styled_func) (info->stream, dis_style_register, "%%macsr");
728       break;
729 
730     case 'H':
731       (*info->fprintf_styled_func) (info->stream, dis_style_register, "%%mask");
732       break;
733 
734     case 'J':
735       {
736           /* FIXME: There's a problem here, different m68k processors call the
737              same address different names.  The tables below try to get it right
738              using info->mach, but only for v4e.  */
739           struct regname { char * name; int value; };
740           static const struct regname names[] =
741             {
742               {"%sfc", 0x000}, {"%dfc", 0x001}, {"%cacr", 0x002},
743               {"%tc",  0x003}, {"%itt0",0x004}, {"%itt1", 0x005},
744               {"%dtt0",0x006}, {"%dtt1",0x007}, {"%buscr",0x008},
745               {"%rgpiobar", 0x009}, {"%acr4",0x00c},
746               {"%acr5",0x00d}, {"%acr6",0x00e}, {"%acr7", 0x00f},
747               {"%usp", 0x800}, {"%vbr", 0x801}, {"%caar", 0x802},
748               {"%msp", 0x803}, {"%isp", 0x804},
749               {"%pc", 0x80f},
750               /* Reg c04 is sometimes called flashbar or rambar.
751                  Reg c05 is also sometimes called rambar.  */
752               {"%rambar0", 0xc04}, {"%rambar1", 0xc05},
753 
754               /* reg c0e is sometimes called mbar2 or secmbar.
755                  reg c0f is sometimes called mbar.  */
756               {"%mbar0", 0xc0e}, {"%mbar1", 0xc0f},
757 
758               /* Should we be calling this psr like we do in case 'Y'?  */
759               {"%mmusr",0x805},
760 
761               {"%urp", 0x806}, {"%srp", 0x807}, {"%pcr", 0x808},
762 
763               /* Fido added these.  */
764               {"%cac", 0xffe}, {"%mbo", 0xfff}
765           };
766           /* Alternate names for v4e (MCF5407/5445x/MCF547x/MCF548x), at least.  */
767           static const struct regname names_v4e[] =
768             {
769               {"%asid",0x003}, {"%acr0",0x004}, {"%acr1",0x005},
770               {"%acr2",0x006}, {"%acr3",0x007}, {"%mmubar",0x008},
771             };
772           unsigned int arch_mask;
773 
774           arch_mask = bfd_m68k_mach_to_features (info->mach);
775           FETCH_ARG (12, val);
776           if (arch_mask & (mcfisa_b | mcfisa_c))
777             {
778               for (regno = ARRAY_SIZE (names_v4e); --regno >= 0;)
779                 if (names_v4e[regno].value == val)
780                     {
781                       (*info->fprintf_styled_func) (info->stream, dis_style_register,
782                                                                  "%s", names_v4e[regno].name);
783                       break;
784                     }
785               if (regno >= 0)
786                 break;
787             }
788           for (regno = ARRAY_SIZE (names) - 1; regno >= 0; regno--)
789             if (names[regno].value == val)
790               {
791                 (*info->fprintf_styled_func) (info->stream, dis_style_register,
792                                                       "%s", names[regno].name);
793                 break;
794               }
795           if (regno < 0)
796             (*info->fprintf_styled_func) (info->stream, dis_style_text, "0x%x", val);
797       }
798       break;
799 
800     case 'Q':
801       FETCH_ARG (3, val);
802       /* 0 means 8, except for the bkpt instruction... */
803       if (val == 0 && d[1] != 's')
804           val = 8;
805       (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
806                                             "#%d", val);
807       break;
808 
809     case 'x':
810       FETCH_ARG (3, val);
811       /* 0 means -1.  */
812       if (val == 0)
813           val = -1;
814       (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
815                                             "#%d", val);
816       break;
817 
818     case 'j':
819       FETCH_ARG (3, val);
820       (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
821                                             "#%d", val+1);
822       break;
823 
824     case 'K':
825       FETCH_ARG (9, val);
826       (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
827                                             "#%d", val);
828       break;
829 
830     case 'M':
831       if (place == 'h')
832           {
833             static char *const scalefactor_name[] = { "<<", ">>" };
834 
835             FETCH_ARG (1, val);
836             (*info->fprintf_styled_func) (info->stream, dis_style_sub_mnemonic,
837                                                   "%s", scalefactor_name[val]);
838           }
839       else
840           {
841             FETCH_ARG (8, val);
842             if (val & 0x80)
843               val = val - 0x100;
844             (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
845                                                   "#%d", val);
846           }
847       break;
848 
849     case 'T':
850       FETCH_ARG (4, val);
851       (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
852                                             "#%d", val);
853       break;
854 
855     case 'D':
856       FETCH_ARG (3, val);
857       (*info->fprintf_styled_func) (info->stream, dis_style_register,
858                                             "%s", reg_names[val]);
859       break;
860 
861     case 'A':
862       FETCH_ARG (3, val);
863       (*info->fprintf_styled_func) (info->stream, dis_style_register,
864                                             "%s", reg_names[val + 010]);
865       break;
866 
867     case 'R':
868       FETCH_ARG (4, val);
869       (*info->fprintf_styled_func) (info->stream, dis_style_register,
870                                             "%s", reg_names[val]);
871       break;
872 
873     case 'r':
874       FETCH_ARG (4, regno);
875       if (regno > 7)
876           {
877             (*info->fprintf_styled_func) (info->stream, dis_style_register,
878                                                   "%s", reg_names[regno]);
879             (*info->fprintf_styled_func) (info->stream, dis_style_text, "@");
880           }
881       else
882           {
883             (*info->fprintf_styled_func) (info->stream, dis_style_text, "@(");
884             (*info->fprintf_styled_func) (info->stream, dis_style_register,
885                                                   "%s", reg_names[regno]);
886             (*info->fprintf_styled_func) (info->stream, dis_style_text, ")");
887           }
888       break;
889 
890     case 'F':
891       FETCH_ARG (3, val);
892       (*info->fprintf_styled_func) (info->stream, dis_style_register,
893                                             "%%fp%d", val);
894       break;
895 
896     case 'O':
897       FETCH_ARG (6, val);
898       if (val & 0x20)
899           (*info->fprintf_styled_func) (info->stream, dis_style_register,
900                                               "%s", reg_names[val & 7]);
901       else
902           (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
903                                               "%d", val);
904       break;
905 
906     case '+':
907       FETCH_ARG (3, val);
908       (*info->fprintf_styled_func) (info->stream, dis_style_register,
909                                             "%s", reg_names[val + 8]);
910       (*info->fprintf_styled_func) (info->stream, dis_style_text, "@+");
911       break;
912 
913     case '-':
914       FETCH_ARG (3, val);
915       (*info->fprintf_styled_func) (info->stream, dis_style_register,
916                                             "%s", reg_names[val + 8]);
917       (*info->fprintf_styled_func) (info->stream, dis_style_text, "@-");
918       break;
919 
920     case 'k':
921       if (place == 'k')
922           {
923             FETCH_ARG (3, val);
924             (*info->fprintf_styled_func) (info->stream, dis_style_text, "{");
925             (*info->fprintf_styled_func) (info->stream, dis_style_register,
926                                                   "%s", reg_names[val]);
927             (*info->fprintf_styled_func) (info->stream, dis_style_text, "}");
928           }
929       else if (place == 'C')
930           {
931             FETCH_ARG (7, val);
932             if (val > 63)               /* This is a signed constant.  */
933               val -= 128;
934             (*info->fprintf_styled_func) (info->stream, dis_style_text, "{");
935             (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
936                                                   "#%d", val);
937             (*info->fprintf_styled_func) (info->stream, dis_style_text, "}");
938           }
939       else
940           return PRINT_INSN_ARG_INVALID_OPERAND;
941       break;
942 
943     case '#':
944     case '^':
945       p1 = buffer + (*d == '#' ? 2 : 4);
946       if (place == 's')
947           FETCH_ARG (4, val);
948       else if (place == 'C')
949           FETCH_ARG (7, val);
950       else if (place == '8')
951           FETCH_ARG (3, val);
952       else if (place == '3')
953           FETCH_ARG (8, val);
954       else if (place == 'b')
955           NEXTBYTE (p1, val);
956       else if (place == 'w' || place == 'W')
957           NEXTWORD (p1, val, PRINT_INSN_ARG_MEMORY_ERROR);
958       else if (place == 'l')
959           NEXTLONG (p1, val, PRINT_INSN_ARG_MEMORY_ERROR);
960       else
961           return PRINT_INSN_ARG_INVALID_OP_TABLE;
962 
963       (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
964                                             "#%d", val);
965       break;
966 
967     case 'B':
968       if (place == 'b')
969           NEXTBYTE (p, disp);
970       else if (place == 'B')
971           disp = COERCE_SIGNED_CHAR (buffer[1]);
972       else if (place == 'w' || place == 'W')
973           NEXTWORD (p, disp, PRINT_INSN_ARG_MEMORY_ERROR);
974       else if (place == 'l' || place == 'L' || place == 'C')
975           NEXTLONG (p, disp, PRINT_INSN_ARG_MEMORY_ERROR);
976       else if (place == 'g')
977           {
978             NEXTBYTE (buffer, disp);
979             if (disp == 0)
980               NEXTWORD (p, disp, PRINT_INSN_ARG_MEMORY_ERROR);
981             else if (disp == -1)
982               NEXTLONG (p, disp, PRINT_INSN_ARG_MEMORY_ERROR);
983           }
984       else if (place == 'c')
985           {
986             if (buffer[1] & 0x40)                 /* If bit six is one, long offset.  */
987               NEXTLONG (p, disp, PRINT_INSN_ARG_MEMORY_ERROR);
988             else
989               NEXTWORD (p, disp, PRINT_INSN_ARG_MEMORY_ERROR);
990           }
991       else
992           return PRINT_INSN_ARG_INVALID_OP_TABLE;
993 
994       (*info->print_address_func) (addr + disp, info);
995       break;
996 
997     case 'd':
998       {
999           int val1;
1000 
1001           NEXTWORD (p, val, PRINT_INSN_ARG_MEMORY_ERROR);
1002           FETCH_ARG (3, val1);
1003           (*info->fprintf_styled_func) (info->stream, dis_style_register,
1004                                               "%s", reg_names[val1 + 8]);
1005           (*info->fprintf_styled_func) (info->stream, dis_style_text, "@(");
1006           (*info->fprintf_styled_func) (info->stream, dis_style_address_offset,
1007                                               "%d", val);
1008           (*info->fprintf_styled_func) (info->stream, dis_style_text, ")");
1009           break;
1010       }
1011 
1012     case 's':
1013       FETCH_ARG (3, val);
1014       (*info->fprintf_styled_func) (info->stream, dis_style_register,
1015                                             "%s", fpcr_names[val]);
1016       break;
1017 
1018     case 'e':
1019       FETCH_ARG (2, val);
1020       (*info->fprintf_styled_func) (info->stream, dis_style_register,
1021                                             "%%acc%d", val);
1022       break;
1023 
1024     case 'g':
1025       FETCH_ARG (1, val);
1026       (*info->fprintf_styled_func) (info->stream, dis_style_register,
1027                                             "%%accext%s", val == 0 ? "01" : "23");
1028       break;
1029 
1030     case 'i':
1031       FETCH_ARG (2, val);
1032       if (val == 1)
1033           (*info->fprintf_styled_func) (info->stream, dis_style_sub_mnemonic,
1034                                               "<<");
1035       else if (val == 3)
1036           (*info->fprintf_styled_func) (info->stream, dis_style_sub_mnemonic,
1037                                               ">>");
1038       else
1039           return PRINT_INSN_ARG_INVALID_OPERAND;
1040       break;
1041 
1042     case 'I':
1043       /* Get coprocessor ID... */
1044       val = fetch_arg (buffer, 'd', 3, info);
1045       if (val < 0)
1046           return PRINT_INSN_ARG_MEMORY_ERROR;
1047       if (val != 1)                               /* Unusual coprocessor ID?  */
1048           (*info->fprintf_styled_func) (info->stream, dis_style_text,
1049                                               "(cpid=%d) ", val);
1050       break;
1051 
1052     case '4':
1053     case '*':
1054     case '~':
1055     case '%':
1056     case ';':
1057     case '@':
1058     case '!':
1059     case '$':
1060     case '?':
1061     case '/':
1062     case '&':
1063     case '|':
1064     case '<':
1065     case '>':
1066     case 'm':
1067     case 'n':
1068     case 'o':
1069     case 'p':
1070     case 'q':
1071     case 'v':
1072     case 'b':
1073     case 'w':
1074     case 'y':
1075     case 'z':
1076       if (place == 'd')
1077           {
1078             val = fetch_arg (buffer, 'x', 6, info);
1079             if (val < 0)
1080               return PRINT_INSN_ARG_MEMORY_ERROR;
1081             val = ((val & 7) << 3) + ((val >> 3) & 7);
1082           }
1083       else
1084           {
1085             val = fetch_arg (buffer, 's', 6, info);
1086             if (val < 0)
1087               return PRINT_INSN_ARG_MEMORY_ERROR;
1088           }
1089 
1090       /* If the <ea> is invalid for *d, then reject this match.  */
1091       if (!m68k_valid_ea (*d, val))
1092           return PRINT_INSN_ARG_INVALID_OPERAND;
1093 
1094       /* Get register number assuming address register.  */
1095       regno = (val & 7) + 8;
1096       regname = reg_names[regno];
1097       switch (val >> 3)
1098           {
1099           case 0:
1100             (*info->fprintf_styled_func) (info->stream, dis_style_register,
1101                                                   "%s", reg_names[val]);
1102             break;
1103 
1104           case 1:
1105             (*info->fprintf_styled_func) (info->stream, dis_style_register,
1106                                                   "%s", regname);
1107             break;
1108 
1109           case 2:
1110             (*info->fprintf_styled_func) (info->stream, dis_style_register,
1111                                                   "%s", regname);
1112             (*info->fprintf_styled_func) (info->stream, dis_style_text, "@");
1113             break;
1114 
1115           case 3:
1116             (*info->fprintf_styled_func) (info->stream, dis_style_register,
1117                                                   "%s", regname);
1118             (*info->fprintf_styled_func) (info->stream, dis_style_text, "@+");
1119             break;
1120 
1121           case 4:
1122             (*info->fprintf_styled_func) (info->stream, dis_style_register,
1123                                                   "%s", regname);
1124             (*info->fprintf_styled_func) (info->stream, dis_style_text, "@-");
1125             break;
1126 
1127           case 5:
1128             NEXTWORD (p, val, PRINT_INSN_ARG_MEMORY_ERROR);
1129             (*info->fprintf_styled_func) (info->stream, dis_style_register,
1130                                                   "%s", regname);
1131             (*info->fprintf_styled_func) (info->stream, dis_style_text, "@(");
1132             (*info->fprintf_styled_func) (info->stream, dis_style_address_offset,
1133                                                   "%d", val);
1134             (*info->fprintf_styled_func) (info->stream, dis_style_text, ")");
1135             break;
1136 
1137           case 6:
1138             p = print_indexed (regno, p, addr, info);
1139             if (p == NULL)
1140               return PRINT_INSN_ARG_MEMORY_ERROR;
1141             break;
1142 
1143           case 7:
1144             switch (val & 7)
1145               {
1146               case 0:
1147                 NEXTWORD (p, val, PRINT_INSN_ARG_MEMORY_ERROR);
1148                 (*info->print_address_func) (val, info);
1149                 break;
1150 
1151               case 1:
1152                 NEXTULONG (p, uval);
1153                 (*info->print_address_func) (uval, info);
1154                 break;
1155 
1156               case 2:
1157                 NEXTWORD (p, val, PRINT_INSN_ARG_MEMORY_ERROR);
1158                 (*info->fprintf_styled_func) (info->stream, dis_style_register,
1159                                                       "%%pc");
1160                 (*info->fprintf_styled_func) (info->stream, dis_style_text, "@(");
1161                 (*info->print_address_func) (addr + val, info);
1162                 (*info->fprintf_styled_func) (info->stream, dis_style_text, ")");
1163                 break;
1164 
1165               case 3:
1166                 p = print_indexed (-1, p, addr, info);
1167                 if (p == NULL)
1168                     return PRINT_INSN_ARG_MEMORY_ERROR;
1169                 break;
1170 
1171               case 4:
1172                 flt_p = 1;    /* Assume it's a float... */
1173                 switch (place)
1174                 {
1175                     case 'b':
1176                       NEXTBYTE (p, val);
1177                       flt_p = 0;
1178                       break;
1179 
1180                     case 'w':
1181                       NEXTWORD (p, val, PRINT_INSN_ARG_MEMORY_ERROR);
1182                       flt_p = 0;
1183                       break;
1184 
1185                     case 'l':
1186                       NEXTLONG (p, val, PRINT_INSN_ARG_MEMORY_ERROR);
1187                       flt_p = 0;
1188                       break;
1189 
1190                     case 'f':
1191                       NEXTSINGLE (flval, p);
1192                       break;
1193 
1194                     case 'F':
1195                       NEXTDOUBLE (flval, p);
1196                       break;
1197 
1198                     case 'x':
1199                       NEXTEXTEND (flval, p);
1200                       break;
1201 
1202                     case 'p':
1203                       NEXTPACKED (p, flval);
1204                       break;
1205 
1206                     default:
1207                       return PRINT_INSN_ARG_INVALID_OPERAND;
1208                 }
1209                 if (flt_p)    /* Print a float? */
1210                     (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1211                                                         "#0e%g", flval);
1212                 else
1213                     (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1214                                                         "#%d", val);
1215                 break;
1216 
1217               default:
1218                 return PRINT_INSN_ARG_INVALID_OPERAND;
1219               }
1220           }
1221 
1222       /* If place is '/', then this is the case of the mask bit for
1223            mac/emac loads. Now that the arg has been printed, grab the
1224            mask bit and if set, add a '&' to the arg.  */
1225       if (place == '/')
1226           {
1227             FETCH_ARG (1, val);
1228             if (val)
1229               info->fprintf_styled_func (info->stream, dis_style_text, "&");
1230           }
1231       break;
1232 
1233     case 'L':
1234     case 'l':
1235           if (place == 'w')
1236             {
1237               char doneany;
1238               p1 = buffer + 2;
1239               NEXTWORD (p1, val, PRINT_INSN_ARG_MEMORY_ERROR);
1240               /* Move the pointer ahead if this point is farther ahead
1241                  than the last.  */
1242               p = p1 > p ? p1 : p;
1243               if (val == 0)
1244                 {
1245                     (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1246                                                         "#0");
1247                     break;
1248                 }
1249               if (*d == 'l')
1250                 {
1251                     int newval = 0;
1252 
1253                     for (regno = 0; regno < 16; ++regno)
1254                       if (val & (0x8000 >> regno))
1255                         newval |= 1 << regno;
1256                     val = newval;
1257                 }
1258               val &= 0xffff;
1259               doneany = 0;
1260               for (regno = 0; regno < 16; ++regno)
1261                 if (val & (1 << regno))
1262                     {
1263                       int first_regno;
1264 
1265                       if (doneany)
1266                         (*info->fprintf_styled_func) (info->stream, dis_style_text,
1267                                                               "/");
1268                       doneany = 1;
1269                       (*info->fprintf_styled_func) (info->stream, dis_style_register,
1270                                                             "%s", reg_names[regno]);
1271                       first_regno = regno;
1272                       while (val & (1 << (regno + 1)))
1273                         ++regno;
1274                       if (regno > first_regno)
1275                         {
1276                           (*info->fprintf_styled_func) (info->stream,
1277                                                                 dis_style_text, "-");
1278                           (*info->fprintf_styled_func) (info->stream,
1279                                                                 dis_style_register, "%s",
1280                                                                 reg_names[regno]);
1281                         }
1282                     }
1283             }
1284           else if (place == '3')
1285             {
1286               /* `fmovem' insn.  */
1287               char doneany;
1288 
1289               FETCH_ARG (8, val);
1290               if (val == 0)
1291                 {
1292                     (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1293                                                         "#0");
1294                     break;
1295                 }
1296               if (*d == 'l')
1297                 {
1298                     int newval = 0;
1299 
1300                     for (regno = 0; regno < 8; ++regno)
1301                       if (val & (0x80 >> regno))
1302                         newval |= 1 << regno;
1303                     val = newval;
1304                 }
1305               val &= 0xff;
1306               doneany = 0;
1307               for (regno = 0; regno < 8; ++regno)
1308                 if (val & (1 << regno))
1309                     {
1310                       int first_regno;
1311                       if (doneany)
1312                         (*info->fprintf_styled_func) (info->stream, dis_style_text,
1313                                                               "/");
1314                       doneany = 1;
1315                       (*info->fprintf_styled_func) (info->stream, dis_style_register,
1316                                                             "%%fp%d", regno);
1317                       first_regno = regno;
1318                       while (val & (1 << (regno + 1)))
1319                         ++regno;
1320                       if (regno > first_regno)
1321                         {
1322                           (*info->fprintf_styled_func) (info->stream,
1323                                                                 dis_style_text, "-");
1324                           (*info->fprintf_styled_func) (info->stream,
1325                                                                 dis_style_register,
1326                                                                 "%%fp%d", regno);
1327                         }
1328                     }
1329             }
1330           else if (place == '8')
1331             {
1332               FETCH_ARG (3, val);
1333               /* fmoveml for FP status registers.  */
1334               (*info->fprintf_styled_func) (info->stream, dis_style_register,
1335                                                     "%s", fpcr_names[val]);
1336             }
1337           else
1338             return PRINT_INSN_ARG_INVALID_OP_TABLE;
1339       break;
1340 
1341     case 'X':
1342       place = '8';
1343       /* Fall through.  */
1344     case 'Y':
1345     case 'Z':
1346     case 'W':
1347     case '0':
1348     case '1':
1349     case '2':
1350     case '3':
1351       {
1352           char *name = 0;
1353 
1354           FETCH_ARG (5, val);
1355           switch (val)
1356             {
1357             case 2: name = "%tt0"; break;
1358             case 3: name = "%tt1"; break;
1359             case 0x10: name = "%tc"; break;
1360             case 0x11: name = "%drp"; break;
1361             case 0x12: name = "%srp"; break;
1362             case 0x13: name = "%crp"; break;
1363             case 0x14: name = "%cal"; break;
1364             case 0x15: name = "%val"; break;
1365             case 0x16: name = "%scc"; break;
1366             case 0x17: name = "%ac"; break;
1367             case 0x18: name = "%psr"; break;
1368             case 0x19: name = "%pcsr"; break;
1369             case 0x1c:
1370             case 0x1d:
1371               {
1372                 int break_reg = ((buffer[3] >> 2) & 7);
1373 
1374                 (*info->fprintf_styled_func)
1375                     (info->stream, dis_style_register,
1376                      val == 0x1c ? "%%bad%d" : "%%bac%d", break_reg);
1377               }
1378               break;
1379             default:
1380               (*info->fprintf_styled_func) (info->stream, dis_style_text,
1381                                                     "<mmu register %d>", val);
1382             }
1383           if (name)
1384             (*info->fprintf_styled_func) (info->stream, dis_style_register,
1385                                                   "%s", name);
1386       }
1387       break;
1388 
1389     case 'f':
1390       {
1391           int fc;
1392 
1393           FETCH_ARG (5, fc);
1394           if (fc == 1)
1395             (*info->fprintf_styled_func) (info->stream, dis_style_register,
1396                                                   "%%dfc");
1397           else if (fc == 0)
1398             (*info->fprintf_styled_func) (info->stream, dis_style_register,
1399                                                   "%%sfc");
1400           else
1401             /* xgettext:c-format */
1402             (*info->fprintf_styled_func) (info->stream, dis_style_text,
1403                                                   _("<function code %d>"), fc);
1404       }
1405       break;
1406 
1407     case 'V':
1408       (*info->fprintf_styled_func) (info->stream, dis_style_register, "%%val");
1409       break;
1410 
1411     case 't':
1412       {
1413           int level;
1414 
1415           FETCH_ARG (3, level);
1416           (*info->fprintf_styled_func) (info->stream, dis_style_immediate,
1417                                               "%d", level);
1418       }
1419       break;
1420 
1421     case 'u':
1422       {
1423           short is_upper = 0;
1424           int reg;
1425 
1426           FETCH_ARG (5, reg);
1427           if (reg & 0x10)
1428             {
1429               is_upper = 1;
1430               reg &= 0xf;
1431             }
1432           (*info->fprintf_styled_func) (info->stream, dis_style_register, "%s%s",
1433                                               reg_half_names[reg],
1434                                               is_upper ? "u" : "l");
1435       }
1436       break;
1437 
1438     default:
1439       return PRINT_INSN_ARG_INVALID_OP_TABLE;
1440     }
1441 
1442   return p - p0;
1443 }
1444 
1445 /* Try to match the current instruction to best and if so, return the
1446    number of bytes consumed from the instruction stream, else zero.
1447    Return -1 on memory error.  */
1448 
1449 static int
match_insn_m68k(bfd_vma memaddr,disassemble_info * info,const struct m68k_opcode * best)1450 match_insn_m68k (bfd_vma memaddr,
1451                      disassemble_info * info,
1452                      const struct m68k_opcode * best)
1453 {
1454   unsigned char *save_p;
1455   unsigned char *p;
1456   const char *d;
1457   const char *args = best->args;
1458 
1459   struct private *priv = (struct private *) info->private_data;
1460   bfd_byte *buffer = priv->the_buffer;
1461   fprintf_styled_ftype save_printer = info->fprintf_styled_func;
1462   void (* save_print_address) (bfd_vma, struct disassemble_info *)
1463     = info->print_address_func;
1464 
1465   if (*args == '.')
1466     args++;
1467 
1468   /* Point at first word of argument data,
1469      and at descriptor for first argument.  */
1470   p = buffer + 2;
1471 
1472   /* Figure out how long the fixed-size portion of the instruction is.
1473      The only place this is stored in the opcode table is
1474      in the arguments--look for arguments which specify fields in the 2nd
1475      or 3rd words of the instruction.  */
1476   for (d = args; *d; d += 2)
1477     {
1478       /* I don't think it is necessary to be checking d[0] here;
1479            I suspect all this could be moved to the case statement below.  */
1480       if (d[0] == '#')
1481           {
1482             if (d[1] == 'l' && p - buffer < 6)
1483               p = buffer + 6;
1484             else if (p - buffer < 4 && d[1] != 'C' && d[1] != '8')
1485               p = buffer + 4;
1486           }
1487 
1488       if ((d[0] == 'L' || d[0] == 'l') && d[1] == 'w' && p - buffer < 4)
1489           p = buffer + 4;
1490 
1491       switch (d[1])
1492           {
1493           case '1':
1494           case '2':
1495           case '3':
1496           case '7':
1497           case '8':
1498           case '9':
1499           case 'i':
1500             if (p - buffer < 4)
1501               p = buffer + 4;
1502             break;
1503           case '4':
1504           case '5':
1505           case '6':
1506             if (p - buffer < 6)
1507               p = buffer + 6;
1508             break;
1509           default:
1510             break;
1511           }
1512     }
1513 
1514   /* pflusha is an exceptions.  It takes no arguments but is two words
1515      long.  Recognize it by looking at the lower 16 bits of the mask.  */
1516   if (p - buffer < 4 && (best->match & 0xFFFF) != 0)
1517     p = buffer + 4;
1518 
1519   /* lpstop is another exception.  It takes a one word argument but is
1520      three words long.  */
1521   if (p - buffer < 6
1522       && (best->match & 0xffff) == 0xffff
1523       && args[0] == '#'
1524       && args[1] == 'w')
1525     {
1526       /* Copy the one word argument into the usual location for a one
1527            word argument, to simplify printing it.  We can get away with
1528            this because we know exactly what the second word is, and we
1529            aren't going to print anything based on it.  */
1530       p = buffer + 6;
1531       if (!FETCH_DATA (info, p))
1532           return -1;
1533       buffer[2] = buffer[4];
1534       buffer[3] = buffer[5];
1535     }
1536 
1537   if (!FETCH_DATA (info, p))
1538     return -1;
1539 
1540   save_p = p;
1541   info->print_address_func = dummy_print_address;
1542   info->fprintf_styled_func = dummy_printer;
1543 
1544   /* We scan the operands twice.  The first time we don't print anything,
1545      but look for errors.  */
1546   for (d = args; *d; d += 2)
1547     {
1548       int eaten = print_insn_arg (d, buffer, p, memaddr + (p - buffer), info);
1549 
1550       if (eaten >= 0)
1551           p += eaten;
1552       else if (eaten == PRINT_INSN_ARG_INVALID_OPERAND
1553                  || eaten == PRINT_INSN_ARG_MEMORY_ERROR)
1554           {
1555             info->fprintf_styled_func = save_printer;
1556             info->print_address_func = save_print_address;
1557             return eaten == PRINT_INSN_ARG_MEMORY_ERROR ? -1 : 0;
1558           }
1559       else
1560           {
1561             /* We must restore the print functions before trying to print the
1562                error message.  */
1563             info->fprintf_styled_func = save_printer;
1564             info->print_address_func = save_print_address;
1565             info->fprintf_styled_func (info->stream, dis_style_text,
1566                                              /* xgettext:c-format */
1567                                              _("<internal error in opcode table: %s %s>\n"),
1568                                              best->name, best->args);
1569             return 2;
1570           }
1571     }
1572 
1573   p = save_p;
1574   info->fprintf_styled_func = save_printer;
1575   info->print_address_func = save_print_address;
1576 
1577   d = args;
1578 
1579   info->fprintf_styled_func (info->stream, dis_style_mnemonic, "%s", best->name);
1580 
1581   if (*d)
1582     info->fprintf_styled_func (info->stream, dis_style_text, " ");
1583 
1584   while (*d)
1585     {
1586       p += print_insn_arg (d, buffer, p, memaddr + (p - buffer), info);
1587       d += 2;
1588 
1589       if (*d && *(d - 2) != 'I' && *d != 'k')
1590           info->fprintf_styled_func (info->stream, dis_style_text, ",");
1591     }
1592 
1593   return p - buffer;
1594 }
1595 
1596 /* Try to interpret the instruction at address MEMADDR as one that
1597    can execute on a processor with the features given by ARCH_MASK.
1598    If successful, print the instruction to INFO->STREAM and return
1599    its length in bytes.  Return 0 otherwise.  Return -1 on memory
1600    error.  */
1601 
1602 static int
m68k_scan_mask(bfd_vma memaddr,disassemble_info * info,unsigned int arch_mask)1603 m68k_scan_mask (bfd_vma memaddr, disassemble_info *info,
1604                     unsigned int arch_mask)
1605 {
1606   int i;
1607   const char *d;
1608   static const struct m68k_opcode **opcodes[16];
1609   static int numopcodes[16];
1610   int val;
1611   int major_opcode;
1612 
1613   struct private *priv = (struct private *) info->private_data;
1614   bfd_byte *buffer = priv->the_buffer;
1615 
1616   if (!opcodes[0])
1617     {
1618       /* Speed up the matching by sorting the opcode
1619            table on the upper four bits of the opcode.  */
1620       const struct m68k_opcode **opc_pointer[16];
1621 
1622       /* First count how many opcodes are in each of the sixteen buckets.  */
1623       for (i = 0; i < m68k_numopcodes; i++)
1624           numopcodes[(m68k_opcodes[i].opcode >> 28) & 15]++;
1625 
1626       /* Then create a sorted table of pointers
1627            that point into the unsorted table.  */
1628       opc_pointer[0] = xmalloc (sizeof (struct m68k_opcode *)
1629                                         * m68k_numopcodes);
1630       opcodes[0] = opc_pointer[0];
1631 
1632       for (i = 1; i < 16; i++)
1633           {
1634             opc_pointer[i] = opc_pointer[i - 1] + numopcodes[i - 1];
1635             opcodes[i] = opc_pointer[i];
1636           }
1637 
1638       for (i = 0; i < m68k_numopcodes; i++)
1639           *opc_pointer[(m68k_opcodes[i].opcode >> 28) & 15]++ = &m68k_opcodes[i];
1640     }
1641 
1642   if (!FETCH_DATA (info, buffer + 2))
1643     return -1;
1644   major_opcode = (buffer[0] >> 4) & 15;
1645 
1646   for (i = 0; i < numopcodes[major_opcode]; i++)
1647     {
1648       const struct m68k_opcode *opc = opcodes[major_opcode][i];
1649       unsigned long opcode = opc->opcode;
1650       unsigned long match = opc->match;
1651       const char *args = opc->args;
1652 
1653       if (*args == '.')
1654           args++;
1655 
1656       if (((0xff & buffer[0] & (match >> 24)) == (0xff & (opcode >> 24)))
1657             && ((0xff & buffer[1] & (match >> 16)) == (0xff & (opcode >> 16)))
1658             /* Only fetch the next two bytes if we need to.  */
1659             && (((0xffff & match) == 0)
1660                 ||
1661                 (FETCH_DATA (info, buffer + 4)
1662                  && ((0xff & buffer[2] & (match >> 8)) == (0xff & (opcode >> 8)))
1663                  && ((0xff & buffer[3] & match) == (0xff & opcode)))
1664                 )
1665             && (opc->arch & arch_mask) != 0)
1666           {
1667             /* Don't use for printout the variants of divul and divsl
1668                that have the same register number in two places.
1669                The more general variants will match instead.  */
1670             for (d = args; *d; d += 2)
1671               if (d[1] == 'D')
1672                 break;
1673 
1674             /* Don't use for printout the variants of most floating
1675                point coprocessor instructions which use the same
1676                register number in two places, as above.  */
1677             if (*d == '\0')
1678               for (d = args; *d; d += 2)
1679                 if (d[1] == 't')
1680                     break;
1681 
1682             /* Don't match fmovel with more than one register;
1683                wait for fmoveml.  */
1684             if (*d == '\0')
1685               {
1686                 for (d = args; *d; d += 2)
1687                     {
1688                       if (d[0] == 's' && d[1] == '8')
1689                         {
1690                           val = fetch_arg (buffer, d[1], 3, info);
1691                           if (val < 0)
1692                               return 0;
1693                           if ((val & (val - 1)) != 0)
1694                               break;
1695                         }
1696                     }
1697               }
1698 
1699             /* Don't match FPU insns with non-default coprocessor ID.  */
1700             if (*d == '\0')
1701               {
1702                 for (d = args; *d; d += 2)
1703                     {
1704                       if (d[0] == 'I')
1705                         {
1706                           val = fetch_arg (buffer, 'd', 3, info);
1707                           if (val != 1)
1708                               break;
1709                         }
1710                     }
1711               }
1712 
1713             if (*d == '\0')
1714               if ((val = match_insn_m68k (memaddr, info, opc)))
1715                 return val;
1716           }
1717     }
1718   return 0;
1719 }
1720 
1721 /* Print the m68k instruction at address MEMADDR in debugged memory,
1722    on INFO->STREAM.  Returns length of the instruction, in bytes.  */
1723 
1724 int
print_insn_m68k(bfd_vma memaddr,disassemble_info * info)1725 print_insn_m68k (bfd_vma memaddr, disassemble_info *info)
1726 {
1727   unsigned int arch_mask;
1728   struct private priv;
1729   int val;
1730 
1731   bfd_byte *buffer = priv.the_buffer;
1732 
1733   info->private_data = & priv;
1734   /* Tell objdump to use two bytes per chunk
1735      and six bytes per line for displaying raw data.  */
1736   info->bytes_per_chunk = 2;
1737   info->bytes_per_line = 6;
1738   info->display_endian = BFD_ENDIAN_BIG;
1739   priv.max_fetched = priv.the_buffer;
1740   priv.insn_start = memaddr;
1741 
1742   arch_mask = bfd_m68k_mach_to_features (info->mach);
1743   if (!arch_mask)
1744     {
1745       /* First try printing an m680x0 instruction.  Try printing a Coldfire
1746            one if that fails.  */
1747       val = m68k_scan_mask (memaddr, info, m68k_mask);
1748       if (val <= 0)
1749           val = m68k_scan_mask (memaddr, info, mcf_mask);
1750     }
1751   else
1752     {
1753       val = m68k_scan_mask (memaddr, info, arch_mask);
1754     }
1755 
1756   if (val == 0)
1757     {
1758       /* Handle undefined instructions.  */
1759       info->fprintf_styled_func (info->stream, dis_style_assembler_directive,
1760                                          ".short");
1761       info->fprintf_styled_func (info->stream, dis_style_text, " ");
1762       info->fprintf_styled_func (info->stream, dis_style_immediate,
1763                                          "0x%04x", (buffer[0] << 8) + buffer[1]);
1764     }
1765 
1766   return val ? val : 2;
1767 }
1768