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