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