]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - opcodes/m68k-dis.c
19990502 sourceware import
[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, 1998
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 'J':
508 {
509 static const struct { char *name; int value; } names[]
510 = {{"%sfc", 0x000}, {"%dfc", 0x001}, {"%cacr", 0x002},
511 {"%tc", 0x003}, {"%itt0",0x004}, {"%itt1", 0x005},
512 {"%dtt0",0x006}, {"%dtt1",0x007}, {"%buscr",0x008},
513 {"%usp", 0x800}, {"%vbr", 0x801}, {"%caar", 0x802},
514 {"%msp", 0x803}, {"%isp", 0x804},
515
516 /* Should we be calling this psr like we do in case 'Y'? */
517 {"%mmusr",0x805},
518
519 {"%urp", 0x806}, {"%srp", 0x807}, {"%pcr", 0x808}};
520
521 val = fetch_arg (buffer, place, 12, info);
522 for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--)
523 if (names[regno].value == val)
524 {
525 (*info->fprintf_func) (info->stream, "%s", names[regno].name);
526 break;
527 }
528 if (regno < 0)
529 (*info->fprintf_func) (info->stream, "%d", val);
530 }
531 break;
532
533 case 'Q':
534 val = fetch_arg (buffer, place, 3, info);
535 /* 0 means 8, except for the bkpt instruction... */
536 if (val == 0 && d[1] != 's')
537 val = 8;
538 (*info->fprintf_func) (info->stream, "#%d", val);
539 break;
540
541 case 'M':
542 val = fetch_arg (buffer, place, 8, info);
543 if (val & 0x80)
544 val = val - 0x100;
545 (*info->fprintf_func) (info->stream, "#%d", val);
546 break;
547
548 case 'T':
549 val = fetch_arg (buffer, place, 4, info);
550 (*info->fprintf_func) (info->stream, "#%d", val);
551 break;
552
553 case 'D':
554 (*info->fprintf_func) (info->stream, "%s",
555 reg_names[fetch_arg (buffer, place, 3, info)]);
556 break;
557
558 case 'A':
559 (*info->fprintf_func)
560 (info->stream, "%s",
561 reg_names[fetch_arg (buffer, place, 3, info) + 010]);
562 break;
563
564 case 'R':
565 (*info->fprintf_func)
566 (info->stream, "%s",
567 reg_names[fetch_arg (buffer, place, 4, info)]);
568 break;
569
570 case 'r':
571 regno = fetch_arg (buffer, place, 4, info);
572 if (regno > 7)
573 (*info->fprintf_func) (info->stream, "%s@", reg_names[regno]);
574 else
575 (*info->fprintf_func) (info->stream, "@(%s)", reg_names[regno]);
576 break;
577
578 case 'F':
579 (*info->fprintf_func)
580 (info->stream, "%%fp%d",
581 fetch_arg (buffer, place, 3, info));
582 break;
583
584 case 'O':
585 val = fetch_arg (buffer, place, 6, info);
586 if (val & 0x20)
587 (*info->fprintf_func) (info->stream, "%s", reg_names [val & 7]);
588 else
589 (*info->fprintf_func) (info->stream, "%d", val);
590 break;
591
592 case '+':
593 (*info->fprintf_func)
594 (info->stream, "%s@+",
595 reg_names[fetch_arg (buffer, place, 3, info) + 8]);
596 break;
597
598 case '-':
599 (*info->fprintf_func)
600 (info->stream, "%s@-",
601 reg_names[fetch_arg (buffer, place, 3, info) + 8]);
602 break;
603
604 case 'k':
605 if (place == 'k')
606 (*info->fprintf_func)
607 (info->stream, "{%s}",
608 reg_names[fetch_arg (buffer, place, 3, info)]);
609 else if (place == 'C')
610 {
611 val = fetch_arg (buffer, place, 7, info);
612 if ( val > 63 ) /* This is a signed constant. */
613 val -= 128;
614 (*info->fprintf_func) (info->stream, "{#%d}", val);
615 }
616 else
617 return -2;
618 break;
619
620 case '#':
621 case '^':
622 p1 = buffer + (*d == '#' ? 2 : 4);
623 if (place == 's')
624 val = fetch_arg (buffer, place, 4, info);
625 else if (place == 'C')
626 val = fetch_arg (buffer, place, 7, info);
627 else if (place == '8')
628 val = fetch_arg (buffer, place, 3, info);
629 else if (place == '3')
630 val = fetch_arg (buffer, place, 8, info);
631 else if (place == 'b')
632 val = NEXTBYTE (p1);
633 else if (place == 'w' || place == 'W')
634 val = NEXTWORD (p1);
635 else if (place == 'l')
636 val = NEXTLONG (p1);
637 else
638 return -2;
639 (*info->fprintf_func) (info->stream, "#%d", val);
640 break;
641
642 case 'B':
643 if (place == 'b')
644 disp = NEXTBYTE (p);
645 else if (place == 'B')
646 disp = COERCE_SIGNED_CHAR(buffer[1]);
647 else if (place == 'w' || place == 'W')
648 disp = NEXTWORD (p);
649 else if (place == 'l' || place == 'L' || place == 'C')
650 disp = NEXTLONG (p);
651 else if (place == 'g')
652 {
653 disp = NEXTBYTE (buffer);
654 if (disp == 0)
655 disp = NEXTWORD (p);
656 else if (disp == -1)
657 disp = NEXTLONG (p);
658 }
659 else if (place == 'c')
660 {
661 if (buffer[1] & 0x40) /* If bit six is one, long offset */
662 disp = NEXTLONG (p);
663 else
664 disp = NEXTWORD (p);
665 }
666 else
667 return -2;
668
669 (*info->print_address_func) (addr + disp, info);
670 break;
671
672 case 'd':
673 val = NEXTWORD (p);
674 (*info->fprintf_func)
675 (info->stream, "%s@(%d)",
676 reg_names[fetch_arg (buffer, place, 3, info) + 8], val);
677 break;
678
679 case 's':
680 (*info->fprintf_func) (info->stream, "%s",
681 fpcr_names[fetch_arg (buffer, place, 3, info)]);
682 break;
683
684 case 'I':
685 /* Get coprocessor ID... */
686 val = fetch_arg (buffer, 'd', 3, info);
687
688 if (val != 1) /* Unusual coprocessor ID? */
689 (*info->fprintf_func) (info->stream, "(cpid=%d) ", val);
690 break;
691
692 case '*':
693 case '~':
694 case '%':
695 case ';':
696 case '@':
697 case '!':
698 case '$':
699 case '?':
700 case '/':
701 case '&':
702 case '|':
703 case '<':
704 case '>':
705 case 'm':
706 case 'n':
707 case 'o':
708 case 'p':
709 case 'q':
710 case 'v':
711
712 if (place == 'd')
713 {
714 val = fetch_arg (buffer, 'x', 6, info);
715 val = ((val & 7) << 3) + ((val >> 3) & 7);
716 }
717 else
718 val = fetch_arg (buffer, 's', 6, info);
719
720 /* Get register number assuming address register. */
721 regno = (val & 7) + 8;
722 regname = reg_names[regno];
723 switch (val >> 3)
724 {
725 case 0:
726 (*info->fprintf_func) (info->stream, "%s", reg_names[val]);
727 break;
728
729 case 1:
730 (*info->fprintf_func) (info->stream, "%s", regname);
731 break;
732
733 case 2:
734 (*info->fprintf_func) (info->stream, "%s@", regname);
735 break;
736
737 case 3:
738 (*info->fprintf_func) (info->stream, "%s@+", regname);
739 break;
740
741 case 4:
742 (*info->fprintf_func) (info->stream, "%s@-", regname);
743 break;
744
745 case 5:
746 val = NEXTWORD (p);
747 (*info->fprintf_func) (info->stream, "%s@(%d)", regname, val);
748 break;
749
750 case 6:
751 p = print_indexed (regno, p, addr, info);
752 break;
753
754 case 7:
755 switch (val & 7)
756 {
757 case 0:
758 val = NEXTWORD (p);
759 (*info->print_address_func) (val, info);
760 break;
761
762 case 1:
763 uval = NEXTULONG (p);
764 (*info->print_address_func) (uval, info);
765 break;
766
767 case 2:
768 val = NEXTWORD (p);
769 (*info->fprintf_func) (info->stream, "%%pc@(");
770 (*info->print_address_func) (addr + val, info);
771 (*info->fprintf_func) (info->stream, ")");
772 break;
773
774 case 3:
775 p = print_indexed (-1, p, addr, info);
776 break;
777
778 case 4:
779 flt_p = 1; /* Assume it's a float... */
780 switch( place )
781 {
782 case 'b':
783 val = NEXTBYTE (p);
784 flt_p = 0;
785 break;
786
787 case 'w':
788 val = NEXTWORD (p);
789 flt_p = 0;
790 break;
791
792 case 'l':
793 val = NEXTLONG (p);
794 flt_p = 0;
795 break;
796
797 case 'f':
798 NEXTSINGLE(flval, p);
799 break;
800
801 case 'F':
802 NEXTDOUBLE(flval, p);
803 break;
804
805 case 'x':
806 NEXTEXTEND(flval, p);
807 break;
808
809 case 'p':
810 flval = NEXTPACKED(p);
811 break;
812
813 default:
814 return -1;
815 }
816 if ( flt_p ) /* Print a float? */
817 (*info->fprintf_func) (info->stream, "#%g", flval);
818 else
819 (*info->fprintf_func) (info->stream, "#%d", val);
820 break;
821
822 default:
823 return -1;
824 }
825 }
826 break;
827
828 case 'L':
829 case 'l':
830 if (place == 'w')
831 {
832 char doneany;
833 p1 = buffer + 2;
834 val = NEXTWORD (p1);
835 /* Move the pointer ahead if this point is farther ahead
836 than the last. */
837 p = p1 > p ? p1 : p;
838 if (val == 0)
839 {
840 (*info->fprintf_func) (info->stream, "#0");
841 break;
842 }
843 if (*d == 'l')
844 {
845 register int newval = 0;
846 for (regno = 0; regno < 16; ++regno)
847 if (val & (0x8000 >> regno))
848 newval |= 1 << regno;
849 val = newval;
850 }
851 val &= 0xffff;
852 doneany = 0;
853 for (regno = 0; regno < 16; ++regno)
854 if (val & (1 << regno))
855 {
856 int first_regno;
857 if (doneany)
858 (*info->fprintf_func) (info->stream, "/");
859 doneany = 1;
860 (*info->fprintf_func) (info->stream, "%s", reg_names[regno]);
861 first_regno = regno;
862 while (val & (1 << (regno + 1)))
863 ++regno;
864 if (regno > first_regno)
865 (*info->fprintf_func) (info->stream, "-%s",
866 reg_names[regno]);
867 }
868 }
869 else if (place == '3')
870 {
871 /* `fmovem' insn. */
872 char doneany;
873 val = fetch_arg (buffer, place, 8, info);
874 if (val == 0)
875 {
876 (*info->fprintf_func) (info->stream, "#0");
877 break;
878 }
879 if (*d == 'l')
880 {
881 register int newval = 0;
882 for (regno = 0; regno < 8; ++regno)
883 if (val & (0x80 >> regno))
884 newval |= 1 << regno;
885 val = newval;
886 }
887 val &= 0xff;
888 doneany = 0;
889 for (regno = 0; regno < 8; ++regno)
890 if (val & (1 << regno))
891 {
892 int first_regno;
893 if (doneany)
894 (*info->fprintf_func) (info->stream, "/");
895 doneany = 1;
896 (*info->fprintf_func) (info->stream, "%%fp%d", regno);
897 first_regno = regno;
898 while (val & (1 << (regno + 1)))
899 ++regno;
900 if (regno > first_regno)
901 (*info->fprintf_func) (info->stream, "-%%fp%d", regno);
902 }
903 }
904 else if (place == '8')
905 {
906 /* fmoveml for FP status registers */
907 (*info->fprintf_func) (info->stream, "%s",
908 fpcr_names[fetch_arg (buffer, place, 3,
909 info)]);
910 }
911 else
912 return -2;
913 break;
914
915 case 'X':
916 place = '8';
917 case 'Y':
918 case 'Z':
919 case 'W':
920 case '0':
921 case '1':
922 case '2':
923 case '3':
924 {
925 int val = fetch_arg (buffer, place, 5, info);
926 char *name = 0;
927 switch (val)
928 {
929 case 2: name = "%tt0"; break;
930 case 3: name = "%tt1"; break;
931 case 0x10: name = "%tc"; break;
932 case 0x11: name = "%drp"; break;
933 case 0x12: name = "%srp"; break;
934 case 0x13: name = "%crp"; break;
935 case 0x14: name = "%cal"; break;
936 case 0x15: name = "%val"; break;
937 case 0x16: name = "%scc"; break;
938 case 0x17: name = "%ac"; break;
939 case 0x18: name = "%psr"; break;
940 case 0x19: name = "%pcsr"; break;
941 case 0x1c:
942 case 0x1d:
943 {
944 int break_reg = ((buffer[3] >> 2) & 7);
945 (*info->fprintf_func)
946 (info->stream, val == 0x1c ? "%%bad%d" : "%%bac%d",
947 break_reg);
948 }
949 break;
950 default:
951 (*info->fprintf_func) (info->stream, "<mmu register %d>", val);
952 }
953 if (name)
954 (*info->fprintf_func) (info->stream, "%s", name);
955 }
956 break;
957
958 case 'f':
959 {
960 int fc = fetch_arg (buffer, place, 5, info);
961 if (fc == 1)
962 (*info->fprintf_func) (info->stream, "%%dfc");
963 else if (fc == 0)
964 (*info->fprintf_func) (info->stream, "%%sfc");
965 else
966 /* xgettext:c-format */
967 (*info->fprintf_func) (info->stream, _("<function code %d>"), fc);
968 }
969 break;
970
971 case 'V':
972 (*info->fprintf_func) (info->stream, "%%val");
973 break;
974
975 case 't':
976 {
977 int level = fetch_arg (buffer, place, 3, info);
978 (*info->fprintf_func) (info->stream, "%d", level);
979 }
980 break;
981
982 default:
983 return -2;
984 }
985
986 return p - p0;
987 }
988
989 /* Fetch BITS bits from a position in the instruction specified by CODE.
990 CODE is a "place to put an argument", or 'x' for a destination
991 that is a general address (mode and register).
992 BUFFER contains the instruction. */
993
994 static int
995 fetch_arg (buffer, code, bits, info)
996 unsigned char *buffer;
997 int code;
998 int bits;
999 disassemble_info *info;
1000 {
1001 register int val = 0;
1002 switch (code)
1003 {
1004 case 's':
1005 val = buffer[1];
1006 break;
1007
1008 case 'd': /* Destination, for register or quick. */
1009 val = (buffer[0] << 8) + buffer[1];
1010 val >>= 9;
1011 break;
1012
1013 case 'x': /* Destination, for general arg */
1014 val = (buffer[0] << 8) + buffer[1];
1015 val >>= 6;
1016 break;
1017
1018 case 'k':
1019 FETCH_DATA (info, buffer + 3);
1020 val = (buffer[3] >> 4);
1021 break;
1022
1023 case 'C':
1024 FETCH_DATA (info, buffer + 3);
1025 val = buffer[3];
1026 break;
1027
1028 case '1':
1029 FETCH_DATA (info, buffer + 3);
1030 val = (buffer[2] << 8) + buffer[3];
1031 val >>= 12;
1032 break;
1033
1034 case '2':
1035 FETCH_DATA (info, buffer + 3);
1036 val = (buffer[2] << 8) + buffer[3];
1037 val >>= 6;
1038 break;
1039
1040 case '3':
1041 case 'j':
1042 FETCH_DATA (info, buffer + 3);
1043 val = (buffer[2] << 8) + buffer[3];
1044 break;
1045
1046 case '4':
1047 FETCH_DATA (info, buffer + 5);
1048 val = (buffer[4] << 8) + buffer[5];
1049 val >>= 12;
1050 break;
1051
1052 case '5':
1053 FETCH_DATA (info, buffer + 5);
1054 val = (buffer[4] << 8) + buffer[5];
1055 val >>= 6;
1056 break;
1057
1058 case '6':
1059 FETCH_DATA (info, buffer + 5);
1060 val = (buffer[4] << 8) + buffer[5];
1061 break;
1062
1063 case '7':
1064 FETCH_DATA (info, buffer + 3);
1065 val = (buffer[2] << 8) + buffer[3];
1066 val >>= 7;
1067 break;
1068
1069 case '8':
1070 FETCH_DATA (info, buffer + 3);
1071 val = (buffer[2] << 8) + buffer[3];
1072 val >>= 10;
1073 break;
1074
1075 case '9':
1076 FETCH_DATA (info, buffer + 3);
1077 val = (buffer[2] << 8) + buffer[3];
1078 val >>= 5;
1079 break;
1080
1081 case 'e':
1082 val = (buffer[1] >> 6);
1083 break;
1084
1085 default:
1086 abort ();
1087 }
1088
1089 switch (bits)
1090 {
1091 case 2:
1092 return val & 3;
1093 case 3:
1094 return val & 7;
1095 case 4:
1096 return val & 017;
1097 case 5:
1098 return val & 037;
1099 case 6:
1100 return val & 077;
1101 case 7:
1102 return val & 0177;
1103 case 8:
1104 return val & 0377;
1105 case 12:
1106 return val & 07777;
1107 default:
1108 abort ();
1109 }
1110 }
1111
1112 /* Print an indexed argument. The base register is BASEREG (-1 for pc).
1113 P points to extension word, in buffer.
1114 ADDR is the nominal core address of that extension word. */
1115
1116 static unsigned char *
1117 print_indexed (basereg, p, addr, info)
1118 int basereg;
1119 unsigned char *p;
1120 bfd_vma addr;
1121 disassemble_info *info;
1122 {
1123 register int word;
1124 static char *const scales[] = {"", ":2", ":4", ":8"};
1125 bfd_vma base_disp;
1126 bfd_vma outer_disp;
1127 char buf[40];
1128 char vmabuf[50];
1129
1130 word = NEXTWORD (p);
1131
1132 /* Generate the text for the index register.
1133 Where this will be output is not yet determined. */
1134 sprintf (buf, "%s:%c%s",
1135 reg_names[(word >> 12) & 0xf],
1136 (word & 0x800) ? 'l' : 'w',
1137 scales[(word >> 9) & 3]);
1138
1139 /* Handle the 68000 style of indexing. */
1140
1141 if ((word & 0x100) == 0)
1142 {
1143 base_disp = word & 0xff;
1144 if ((base_disp & 0x80) != 0)
1145 base_disp -= 0x100;
1146 if (basereg == -1)
1147 base_disp += addr;
1148 print_base (basereg, base_disp, info);
1149 (*info->fprintf_func) (info->stream, ",%s)", buf);
1150 return p;
1151 }
1152
1153 /* Handle the generalized kind. */
1154 /* First, compute the displacement to add to the base register. */
1155
1156 if (word & 0200)
1157 {
1158 if (basereg == -1)
1159 basereg = -3;
1160 else
1161 basereg = -2;
1162 }
1163 if (word & 0100)
1164 buf[0] = '\0';
1165 base_disp = 0;
1166 switch ((word >> 4) & 3)
1167 {
1168 case 2:
1169 base_disp = NEXTWORD (p);
1170 break;
1171 case 3:
1172 base_disp = NEXTLONG (p);
1173 }
1174 if (basereg == -1)
1175 base_disp += addr;
1176
1177 /* Handle single-level case (not indirect) */
1178
1179 if ((word & 7) == 0)
1180 {
1181 print_base (basereg, base_disp, info);
1182 if (buf[0] != '\0')
1183 (*info->fprintf_func) (info->stream, ",%s", buf);
1184 (*info->fprintf_func) (info->stream, ")");
1185 return p;
1186 }
1187
1188 /* Two level. Compute displacement to add after indirection. */
1189
1190 outer_disp = 0;
1191 switch (word & 3)
1192 {
1193 case 2:
1194 outer_disp = NEXTWORD (p);
1195 break;
1196 case 3:
1197 outer_disp = NEXTLONG (p);
1198 }
1199
1200 print_base (basereg, base_disp, info);
1201 if ((word & 4) == 0 && buf[0] != '\0')
1202 {
1203 (*info->fprintf_func) (info->stream, ",%s", buf);
1204 buf[0] = '\0';
1205 }
1206 sprintf_vma (vmabuf, outer_disp);
1207 (*info->fprintf_func) (info->stream, ")@(%s", vmabuf);
1208 if (buf[0] != '\0')
1209 (*info->fprintf_func) (info->stream, ",%s", buf);
1210 (*info->fprintf_func) (info->stream, ")");
1211
1212 return p;
1213 }
1214
1215 /* Print a base register REGNO and displacement DISP, on INFO->STREAM.
1216 REGNO = -1 for pc, -2 for none (suppressed). */
1217
1218 static void
1219 print_base (regno, disp, info)
1220 int regno;
1221 bfd_vma disp;
1222 disassemble_info *info;
1223 {
1224 if (regno == -1)
1225 {
1226 (*info->fprintf_func) (info->stream, "%%pc@(");
1227 (*info->print_address_func) (disp, info);
1228 }
1229 else
1230 {
1231 char buf[50];
1232
1233 if (regno == -2)
1234 (*info->fprintf_func) (info->stream, "@(");
1235 else if (regno == -3)
1236 (*info->fprintf_func) (info->stream, "%%zpc@(");
1237 else
1238 (*info->fprintf_func) (info->stream, "%s@(", reg_names[regno]);
1239
1240 sprintf_vma (buf, disp);
1241 (*info->fprintf_func) (info->stream, "%s", buf);
1242 }
1243 }