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