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