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