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