1 /* Print Motorola 68k instructions.
2 Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
3 1998, 1999, 2000, 2001, 2002, 2003
4 Free Software Foundation, Inc.
6 This file is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 #include "floatformat.h"
23 #include "libiberty.h"
26 #include "opcode/m68k.h"
28 /* Local function prototypes */
31 fetch_data
PARAMS ((struct disassemble_info
*, bfd_byte
*));
34 dummy_print_address
PARAMS ((bfd_vma
, struct disassemble_info
*));
37 fetch_arg
PARAMS ((unsigned char *, int, int, disassemble_info
*));
40 print_base
PARAMS ((int, bfd_vma
, disassemble_info
*));
42 static unsigned char *
43 print_indexed
PARAMS ((int, unsigned char *, bfd_vma
, disassemble_info
*));
46 print_insn_arg
PARAMS ((const char *, unsigned char *, unsigned char *,
47 bfd_vma
, disassemble_info
*));
49 const char * const fpcr_names
[] = {
50 "", "%fpiar", "%fpsr", "%fpiar/%fpsr", "%fpcr",
51 "%fpiar/%fpcr", "%fpsr/%fpcr", "%fpiar/%fpsr/%fpcr"
54 static char *const reg_names
[] = {
55 "%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7",
56 "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%fp", "%sp",
60 /* Sign-extend an (unsigned char). */
62 #define COERCE_SIGNED_CHAR(ch) ((signed char) (ch))
64 #define COERCE_SIGNED_CHAR(ch) ((int) (((ch) ^ 0x80) & 0xFF) - 128)
67 /* Get a 1 byte signed integer. */
68 #define NEXTBYTE(p) (p += 2, FETCH_DATA (info, p), COERCE_SIGNED_CHAR(p[-1]))
70 /* Get a 2 byte signed integer. */
71 #define COERCE16(x) ((int) (((x) ^ 0x8000) - 0x8000))
73 (p += 2, FETCH_DATA (info, p), \
74 COERCE16 ((p[-2] << 8) + p[-1]))
76 /* Get a 4 byte signed integer. */
77 #define COERCE32(x) ((bfd_signed_vma) ((x) ^ 0x80000000) - 0x80000000)
79 (p += 4, FETCH_DATA (info, p), \
80 (COERCE32 ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])))
82 /* Get a 4 byte unsigned integer. */
83 #define NEXTULONG(p) \
84 (p += 4, FETCH_DATA (info, p), \
85 (unsigned int) ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1]))
87 /* Get a single precision float. */
88 #define NEXTSINGLE(val, p) \
89 (p += 4, FETCH_DATA (info, p), \
90 floatformat_to_double (&floatformat_ieee_single_big, (char *) p - 4, &val))
92 /* Get a double precision float. */
93 #define NEXTDOUBLE(val, p) \
94 (p += 8, FETCH_DATA (info, p), \
95 floatformat_to_double (&floatformat_ieee_double_big, (char *) p - 8, &val))
97 /* Get an extended precision float. */
98 #define NEXTEXTEND(val, p) \
99 (p += 12, FETCH_DATA (info, p), \
100 floatformat_to_double (&floatformat_m68881_ext, (char *) p - 12, &val))
102 /* Need a function to convert from packed to double
103 precision. Actually, it's easier to print a
104 packed number than a double anyway, so maybe
105 there should be a special case to handle this... */
106 #define NEXTPACKED(p) \
107 (p += 12, FETCH_DATA (info, p), 0.0)
109 /* Maximum length of an instruction. */
115 /* Points to first byte not fetched. */
116 bfd_byte
*max_fetched
;
117 bfd_byte the_buffer
[MAXLEN
];
122 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
123 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
125 #define FETCH_DATA(info, addr) \
126 ((addr) <= ((struct private *) (info->private_data))->max_fetched \
127 ? 1 : fetch_data ((info), (addr)))
130 fetch_data (info
, addr
)
131 struct disassemble_info
*info
;
135 struct private *priv
= (struct private *)info
->private_data
;
136 bfd_vma start
= priv
->insn_start
+ (priv
->max_fetched
- priv
->the_buffer
);
138 status
= (*info
->read_memory_func
) (start
,
140 addr
- priv
->max_fetched
,
144 (*info
->memory_error_func
) (status
, start
, info
);
145 longjmp (priv
->bailout
, 1);
148 priv
->max_fetched
= addr
;
152 /* This function is used to print to the bit-bucket. */
155 dummy_printer (FILE *file ATTRIBUTE_UNUSED
,
156 const char *format ATTRIBUTE_UNUSED
, ...)
159 FILE *file ATTRIBUTE_UNUSED
;
166 dummy_print_address (vma
, info
)
167 bfd_vma vma ATTRIBUTE_UNUSED
;
168 struct disassemble_info
*info ATTRIBUTE_UNUSED
;
172 /* Print the m68k instruction at address MEMADDR in debugged memory,
173 on INFO->STREAM. Returns length of the instruction, in bytes. */
176 print_insn_m68k (memaddr
, info
)
178 disassemble_info
*info
;
181 register unsigned char *p
;
182 unsigned char *save_p
;
183 register const char *d
;
184 register unsigned long bestmask
;
185 const struct m68k_opcode
*best
;
186 unsigned int arch_mask
;
188 bfd_byte
*buffer
= priv
.the_buffer
;
189 fprintf_ftype save_printer
= info
->fprintf_func
;
190 void (*save_print_address
) PARAMS ((bfd_vma
, struct disassemble_info
*))
191 = info
->print_address_func
;
193 static int numopcodes
[16];
194 static const struct m68k_opcode
**opcodes
[16];
198 /* Speed up the matching by sorting the opcode table on the upper
199 four bits of the opcode. */
200 const struct m68k_opcode
**opc_pointer
[16];
202 /* First count how many opcodes are in each of the sixteen buckets. */
203 for (i
= 0; i
< m68k_numopcodes
; i
++)
204 numopcodes
[(m68k_opcodes
[i
].opcode
>> 28) & 15]++;
206 /* Then create a sorted table of pointers that point into the
208 opc_pointer
[0] = ((const struct m68k_opcode
**)
209 xmalloc (sizeof (struct m68k_opcode
*)
211 opcodes
[0] = opc_pointer
[0];
212 for (i
= 1; i
< 16; i
++)
214 opc_pointer
[i
] = opc_pointer
[i
- 1] + numopcodes
[i
- 1];
215 opcodes
[i
] = opc_pointer
[i
];
218 for (i
= 0; i
< m68k_numopcodes
; i
++)
219 *opc_pointer
[(m68k_opcodes
[i
].opcode
>> 28) & 15]++ = &m68k_opcodes
[i
];
223 info
->private_data
= (PTR
) &priv
;
224 /* Tell objdump to use two bytes per chunk and six bytes per line for
225 displaying raw data. */
226 info
->bytes_per_chunk
= 2;
227 info
->bytes_per_line
= 6;
228 info
->display_endian
= BFD_ENDIAN_BIG
;
229 priv
.max_fetched
= priv
.the_buffer
;
230 priv
.insn_start
= memaddr
;
231 if (setjmp (priv
.bailout
) != 0)
240 arch_mask
= (unsigned int) -1;
242 case bfd_mach_m68000
:
245 case bfd_mach_m68008
:
248 case bfd_mach_m68010
:
251 case bfd_mach_m68020
:
254 case bfd_mach_m68030
:
257 case bfd_mach_m68040
:
260 case bfd_mach_m68060
:
263 case bfd_mach_mcf5200
:
266 case bfd_mach_mcf528x
:
269 case bfd_mach_mcf5206e
:
270 arch_mask
= mcf5206e
;
272 case bfd_mach_mcf5307
:
275 case bfd_mach_mcf5407
:
280 arch_mask
|= m68881
| m68851
;
283 FETCH_DATA (info
, buffer
+ 2);
284 major_opcode
= (buffer
[0] >> 4) & 15;
285 for (i
= 0; i
< numopcodes
[major_opcode
]; i
++)
287 const struct m68k_opcode
*opc
= opcodes
[major_opcode
][i
];
288 unsigned long opcode
= opc
->opcode
;
289 unsigned long match
= opc
->match
;
291 if (((0xff & buffer
[0] & (match
>> 24)) == (0xff & (opcode
>> 24)))
292 && ((0xff & buffer
[1] & (match
>> 16)) == (0xff & (opcode
>> 16)))
293 /* Only fetch the next two bytes if we need to. */
294 && (((0xffff & match
) == 0)
296 (FETCH_DATA (info
, buffer
+ 4)
297 && ((0xff & buffer
[2] & (match
>> 8)) == (0xff & (opcode
>> 8)))
298 && ((0xff & buffer
[3] & match
) == (0xff & opcode
)))
300 && (opc
->arch
& arch_mask
) != 0)
302 /* Don't use for printout the variants of divul and divsl
303 that have the same register number in two places.
304 The more general variants will match instead. */
305 for (d
= opc
->args
; *d
; d
+= 2)
309 /* Don't use for printout the variants of most floating
310 point coprocessor instructions which use the same
311 register number in two places, as above. */
313 for (d
= opc
->args
; *d
; d
+= 2)
317 /* Don't match fmovel with more than one register; wait for
321 for (d
= opc
->args
; *d
; d
+= 2)
323 if (d
[0] == 's' && d
[1] == '8')
327 val
= fetch_arg (buffer
, d
[1], 3, info
);
328 if ((val
& (val
- 1)) != 0)
334 if (*d
== '\0' && match
> bestmask
)
345 /* Point at first word of argument data,
346 and at descriptor for first argument. */
349 /* Figure out how long the fixed-size portion of the instruction is.
350 The only place this is stored in the opcode table is
351 in the arguments--look for arguments which specify fields in the 2nd
352 or 3rd words of the instruction. */
353 for (d
= best
->args
; *d
; d
+= 2)
355 /* I don't think it is necessary to be checking d[0] here; I suspect
356 all this could be moved to the case statement below. */
359 if (d
[1] == 'l' && p
- buffer
< 6)
361 else if (p
- buffer
< 4 && d
[1] != 'C' && d
[1] != '8')
364 if ((d
[0] == 'L' || d
[0] == 'l') && d
[1] == 'w' && p
- buffer
< 4)
389 /* pflusha is an exceptions. It takes no arguments but is two words
390 long. Recognize it by looking at the lower 16 bits of the mask. */
391 if (p
- buffer
< 4 && (best
->match
& 0xFFFF) != 0)
394 /* lpstop is another exception. It takes a one word argument but is
397 && (best
->match
& 0xffff) == 0xffff
398 && best
->args
[0] == '#'
399 && best
->args
[1] == 'w')
401 /* Copy the one word argument into the usual location for a one
402 word argument, to simplify printing it. We can get away with
403 this because we know exactly what the second word is, and we
404 aren't going to print anything based on it. */
406 FETCH_DATA (info
, p
);
407 buffer
[2] = buffer
[4];
408 buffer
[3] = buffer
[5];
411 FETCH_DATA (info
, p
);
415 /* We scan the operands twice. The first time we don't print anything,
416 but look for errors. */
419 info
->print_address_func
= dummy_print_address
;
420 info
->fprintf_func
= (fprintf_ftype
) dummy_printer
;
423 int eaten
= print_insn_arg (d
, buffer
, p
, memaddr
+ (p
- buffer
), info
);
426 else if (eaten
== -1)
430 (*info
->fprintf_func
) (info
->stream
,
431 /* xgettext:c-format */
432 _("<internal error in opcode table: %s %s>\n"),
440 info
->fprintf_func
= save_printer
;
441 info
->print_address_func
= save_print_address
;
445 (*info
->fprintf_func
) (info
->stream
, "%s", best
->name
);
448 (*info
->fprintf_func
) (info
->stream
, " ");
452 p
+= print_insn_arg (d
, buffer
, p
, memaddr
+ (p
- buffer
), info
);
454 if (*d
&& *(d
- 2) != 'I' && *d
!= 'k')
455 (*info
->fprintf_func
) (info
->stream
, ",");
460 /* Handle undefined instructions. */
461 info
->fprintf_func
= save_printer
;
462 info
->print_address_func
= save_print_address
;
463 (*info
->fprintf_func
) (info
->stream
, "0%o",
464 (buffer
[0] << 8) + buffer
[1]);
468 /* Returns number of bytes "eaten" by the operand, or
469 return -1 if an invalid operand was found, or -2 if
470 an opcode tabe error was found. */
473 print_insn_arg (d
, buffer
, p0
, addr
, info
)
475 unsigned char *buffer
;
477 bfd_vma addr
; /* PC for this arg to be relative to */
478 disassemble_info
*info
;
480 register int val
= 0;
481 register int place
= d
[1];
482 register unsigned char *p
= p0
;
484 register const char *regname
;
485 register unsigned char *p1
;
493 case 'c': /* cache identifier */
495 static char *const cacheFieldName
[] = { "nc", "dc", "ic", "bc" };
496 val
= fetch_arg (buffer
, place
, 2, info
);
497 (*info
->fprintf_func
) (info
->stream
, cacheFieldName
[val
]);
501 case 'a': /* address register indirect only. Cf. case '+'. */
503 (*info
->fprintf_func
)
506 reg_names
[fetch_arg (buffer
, place
, 3, info
) + 8]);
510 case '_': /* 32-bit absolute address for move16. */
512 uval
= NEXTULONG (p
);
513 (*info
->print_address_func
) (uval
, info
);
518 (*info
->fprintf_func
) (info
->stream
, "%%ccr");
522 (*info
->fprintf_func
) (info
->stream
, "%%sr");
526 (*info
->fprintf_func
) (info
->stream
, "%%usp");
530 (*info
->fprintf_func
) (info
->stream
, "%%acc");
534 (*info
->fprintf_func
) (info
->stream
, "%%macsr");
538 (*info
->fprintf_func
) (info
->stream
, "%%mask");
543 /* FIXME: There's a problem here, different m68k processors call the
544 same address different names. This table can't get it right
545 because it doesn't know which processor it's disassembling for. */
546 static const struct { char *name
; int value
; } names
[]
547 = {{"%sfc", 0x000}, {"%dfc", 0x001}, {"%cacr", 0x002},
548 {"%tc", 0x003}, {"%itt0",0x004}, {"%itt1", 0x005},
549 {"%dtt0",0x006}, {"%dtt1",0x007}, {"%buscr",0x008},
550 {"%usp", 0x800}, {"%vbr", 0x801}, {"%caar", 0x802},
551 {"%msp", 0x803}, {"%isp", 0x804},
552 {"%flashbar", 0xc04}, {"%rambar", 0xc05}, /* mcf528x added these. */
554 /* Should we be calling this psr like we do in case 'Y'? */
557 {"%urp", 0x806}, {"%srp", 0x807}, {"%pcr", 0x808}};
559 val
= fetch_arg (buffer
, place
, 12, info
);
560 for (regno
= sizeof names
/ sizeof names
[0] - 1; regno
>= 0; regno
--)
561 if (names
[regno
].value
== val
)
563 (*info
->fprintf_func
) (info
->stream
, "%s", names
[regno
].name
);
567 (*info
->fprintf_func
) (info
->stream
, "%d", val
);
572 val
= fetch_arg (buffer
, place
, 3, info
);
573 /* 0 means 8, except for the bkpt instruction... */
574 if (val
== 0 && d
[1] != 's')
576 (*info
->fprintf_func
) (info
->stream
, "#%d", val
);
580 val
= fetch_arg (buffer
, place
, 3, info
);
584 (*info
->fprintf_func
) (info
->stream
, "#%d", val
);
590 static char *const scalefactor_name
[] = { "<<", ">>" };
591 val
= fetch_arg (buffer
, place
, 1, info
);
592 (*info
->fprintf_func
) (info
->stream
, scalefactor_name
[val
]);
596 val
= fetch_arg (buffer
, place
, 8, info
);
599 (*info
->fprintf_func
) (info
->stream
, "#%d", val
);
604 val
= fetch_arg (buffer
, place
, 4, info
);
605 (*info
->fprintf_func
) (info
->stream
, "#%d", val
);
609 (*info
->fprintf_func
) (info
->stream
, "%s",
610 reg_names
[fetch_arg (buffer
, place
, 3, info
)]);
614 (*info
->fprintf_func
)
616 reg_names
[fetch_arg (buffer
, place
, 3, info
) + 010]);
620 (*info
->fprintf_func
)
622 reg_names
[fetch_arg (buffer
, place
, 4, info
)]);
626 regno
= fetch_arg (buffer
, place
, 4, info
);
628 (*info
->fprintf_func
) (info
->stream
, "%s@", reg_names
[regno
]);
630 (*info
->fprintf_func
) (info
->stream
, "@(%s)", reg_names
[regno
]);
634 (*info
->fprintf_func
)
635 (info
->stream
, "%%fp%d",
636 fetch_arg (buffer
, place
, 3, info
));
640 val
= fetch_arg (buffer
, place
, 6, info
);
642 (*info
->fprintf_func
) (info
->stream
, "%s", reg_names
[val
& 7]);
644 (*info
->fprintf_func
) (info
->stream
, "%d", val
);
648 (*info
->fprintf_func
)
649 (info
->stream
, "%s@+",
650 reg_names
[fetch_arg (buffer
, place
, 3, info
) + 8]);
654 (*info
->fprintf_func
)
655 (info
->stream
, "%s@-",
656 reg_names
[fetch_arg (buffer
, place
, 3, info
) + 8]);
661 (*info
->fprintf_func
)
662 (info
->stream
, "{%s}",
663 reg_names
[fetch_arg (buffer
, place
, 3, info
)]);
664 else if (place
== 'C')
666 val
= fetch_arg (buffer
, place
, 7, info
);
667 if (val
> 63) /* This is a signed constant. */
669 (*info
->fprintf_func
) (info
->stream
, "{#%d}", val
);
677 p1
= buffer
+ (*d
== '#' ? 2 : 4);
679 val
= fetch_arg (buffer
, place
, 4, info
);
680 else if (place
== 'C')
681 val
= fetch_arg (buffer
, place
, 7, info
);
682 else if (place
== '8')
683 val
= fetch_arg (buffer
, place
, 3, info
);
684 else if (place
== '3')
685 val
= fetch_arg (buffer
, place
, 8, info
);
686 else if (place
== 'b')
688 else if (place
== 'w' || place
== 'W')
690 else if (place
== 'l')
694 (*info
->fprintf_func
) (info
->stream
, "#%d", val
);
700 else if (place
== 'B')
701 disp
= COERCE_SIGNED_CHAR (buffer
[1]);
702 else if (place
== 'w' || place
== 'W')
704 else if (place
== 'l' || place
== 'L' || place
== 'C')
706 else if (place
== 'g')
708 disp
= NEXTBYTE (buffer
);
714 else if (place
== 'c')
716 if (buffer
[1] & 0x40) /* If bit six is one, long offset */
724 (*info
->print_address_func
) (addr
+ disp
, info
);
729 (*info
->fprintf_func
)
730 (info
->stream
, "%s@(%d)",
731 reg_names
[fetch_arg (buffer
, place
, 3, info
) + 8], val
);
735 (*info
->fprintf_func
) (info
->stream
, "%s",
736 fpcr_names
[fetch_arg (buffer
, place
, 3, info
)]);
740 /* Get coprocessor ID... */
741 val
= fetch_arg (buffer
, 'd', 3, info
);
743 if (val
!= 1) /* Unusual coprocessor ID? */
744 (*info
->fprintf_func
) (info
->stream
, "(cpid=%d) ", val
);
772 val
= fetch_arg (buffer
, 'x', 6, info
);
773 val
= ((val
& 7) << 3) + ((val
>> 3) & 7);
776 val
= fetch_arg (buffer
, 's', 6, info
);
778 /* Get register number assuming address register. */
779 regno
= (val
& 7) + 8;
780 regname
= reg_names
[regno
];
784 (*info
->fprintf_func
) (info
->stream
, "%s", reg_names
[val
]);
788 (*info
->fprintf_func
) (info
->stream
, "%s", regname
);
792 (*info
->fprintf_func
) (info
->stream
, "%s@", regname
);
796 (*info
->fprintf_func
) (info
->stream
, "%s@+", regname
);
800 (*info
->fprintf_func
) (info
->stream
, "%s@-", regname
);
805 (*info
->fprintf_func
) (info
->stream
, "%s@(%d)", regname
, val
);
809 p
= print_indexed (regno
, p
, addr
, info
);
817 (*info
->print_address_func
) (val
, info
);
821 uval
= NEXTULONG (p
);
822 (*info
->print_address_func
) (uval
, info
);
827 (*info
->fprintf_func
) (info
->stream
, "%%pc@(");
828 (*info
->print_address_func
) (addr
+ val
, info
);
829 (*info
->fprintf_func
) (info
->stream
, ")");
833 p
= print_indexed (-1, p
, addr
, info
);
837 flt_p
= 1; /* Assume it's a float... */
856 NEXTSINGLE (flval
, p
);
860 NEXTDOUBLE (flval
, p
);
864 NEXTEXTEND (flval
, p
);
868 flval
= NEXTPACKED (p
);
874 if (flt_p
) /* Print a float? */
875 (*info
->fprintf_func
) (info
->stream
, "#%g", flval
);
877 (*info
->fprintf_func
) (info
->stream
, "#%d", val
);
893 /* Move the pointer ahead if this point is farther ahead
898 (*info
->fprintf_func
) (info
->stream
, "#0");
903 register int newval
= 0;
904 for (regno
= 0; regno
< 16; ++regno
)
905 if (val
& (0x8000 >> regno
))
906 newval
|= 1 << regno
;
911 for (regno
= 0; regno
< 16; ++regno
)
912 if (val
& (1 << regno
))
916 (*info
->fprintf_func
) (info
->stream
, "/");
918 (*info
->fprintf_func
) (info
->stream
, "%s", reg_names
[regno
]);
920 while (val
& (1 << (regno
+ 1)))
922 if (regno
> first_regno
)
923 (*info
->fprintf_func
) (info
->stream
, "-%s",
927 else if (place
== '3')
931 val
= fetch_arg (buffer
, place
, 8, info
);
934 (*info
->fprintf_func
) (info
->stream
, "#0");
939 register int newval
= 0;
940 for (regno
= 0; regno
< 8; ++regno
)
941 if (val
& (0x80 >> regno
))
942 newval
|= 1 << regno
;
947 for (regno
= 0; regno
< 8; ++regno
)
948 if (val
& (1 << regno
))
952 (*info
->fprintf_func
) (info
->stream
, "/");
954 (*info
->fprintf_func
) (info
->stream
, "%%fp%d", regno
);
956 while (val
& (1 << (regno
+ 1)))
958 if (regno
> first_regno
)
959 (*info
->fprintf_func
) (info
->stream
, "-%%fp%d", regno
);
962 else if (place
== '8')
964 /* fmoveml for FP status registers */
965 (*info
->fprintf_func
) (info
->stream
, "%s",
966 fpcr_names
[fetch_arg (buffer
, place
, 3,
983 int val
= fetch_arg (buffer
, place
, 5, info
);
987 case 2: name
= "%tt0"; break;
988 case 3: name
= "%tt1"; break;
989 case 0x10: name
= "%tc"; break;
990 case 0x11: name
= "%drp"; break;
991 case 0x12: name
= "%srp"; break;
992 case 0x13: name
= "%crp"; break;
993 case 0x14: name
= "%cal"; break;
994 case 0x15: name
= "%val"; break;
995 case 0x16: name
= "%scc"; break;
996 case 0x17: name
= "%ac"; break;
997 case 0x18: name
= "%psr"; break;
998 case 0x19: name
= "%pcsr"; break;
1002 int break_reg
= ((buffer
[3] >> 2) & 7);
1003 (*info
->fprintf_func
)
1004 (info
->stream
, val
== 0x1c ? "%%bad%d" : "%%bac%d",
1009 (*info
->fprintf_func
) (info
->stream
, "<mmu register %d>", val
);
1012 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
1018 int fc
= fetch_arg (buffer
, place
, 5, info
);
1020 (*info
->fprintf_func
) (info
->stream
, "%%dfc");
1022 (*info
->fprintf_func
) (info
->stream
, "%%sfc");
1024 /* xgettext:c-format */
1025 (*info
->fprintf_func
) (info
->stream
, _("<function code %d>"), fc
);
1030 (*info
->fprintf_func
) (info
->stream
, "%%val");
1035 int level
= fetch_arg (buffer
, place
, 3, info
);
1036 (*info
->fprintf_func
) (info
->stream
, "%d", level
);
1043 int reg
= fetch_arg (buffer
, place
, 5, info
);
1050 (*info
->fprintf_func
) (info
->stream
, "%s%s",
1052 is_upper
? "u" : "l");
1063 /* Fetch BITS bits from a position in the instruction specified by CODE.
1064 CODE is a "place to put an argument", or 'x' for a destination
1065 that is a general address (mode and register).
1066 BUFFER contains the instruction. */
1069 fetch_arg (buffer
, code
, bits
, info
)
1070 unsigned char *buffer
;
1073 disassemble_info
*info
;
1075 register int val
= 0;
1082 case 'd': /* Destination, for register or quick. */
1083 val
= (buffer
[0] << 8) + buffer
[1];
1087 case 'x': /* Destination, for general arg */
1088 val
= (buffer
[0] << 8) + buffer
[1];
1093 FETCH_DATA (info
, buffer
+ 3);
1094 val
= (buffer
[3] >> 4);
1098 FETCH_DATA (info
, buffer
+ 3);
1103 FETCH_DATA (info
, buffer
+ 3);
1104 val
= (buffer
[2] << 8) + buffer
[3];
1109 FETCH_DATA (info
, buffer
+ 3);
1110 val
= (buffer
[2] << 8) + buffer
[3];
1116 FETCH_DATA (info
, buffer
+ 3);
1117 val
= (buffer
[2] << 8) + buffer
[3];
1121 FETCH_DATA (info
, buffer
+ 5);
1122 val
= (buffer
[4] << 8) + buffer
[5];
1127 FETCH_DATA (info
, buffer
+ 5);
1128 val
= (buffer
[4] << 8) + buffer
[5];
1133 FETCH_DATA (info
, buffer
+ 5);
1134 val
= (buffer
[4] << 8) + buffer
[5];
1138 FETCH_DATA (info
, buffer
+ 3);
1139 val
= (buffer
[2] << 8) + buffer
[3];
1144 FETCH_DATA (info
, buffer
+ 3);
1145 val
= (buffer
[2] << 8) + buffer
[3];
1150 FETCH_DATA (info
, buffer
+ 3);
1151 val
= (buffer
[2] << 8) + buffer
[3];
1156 val
= (buffer
[1] >> 6);
1160 val
= (buffer
[1] & 0x40 ? 0x8 : 0)
1161 | ((buffer
[0] >> 1) & 0x7)
1162 | (buffer
[3] & 0x80 ? 0x10 : 0);
1166 val
= (buffer
[1] & 0x40 ? 0x8 : 0) | ((buffer
[0] >> 1) & 0x7);
1170 val
= (buffer
[2] >> 4) | (buffer
[3] & 0x80 ? 0x10 : 0);
1174 val
= buffer
[1] | (buffer
[3] & 0x40 ? 0x10 : 0);
1178 val
= buffer
[3] | (buffer
[3] & 0x40 ? 0x10 : 0);
1182 val
= buffer
[2] >> 2;
1214 /* Print an indexed argument. The base register is BASEREG (-1 for pc).
1215 P points to extension word, in buffer.
1216 ADDR is the nominal core address of that extension word. */
1218 static unsigned char *
1219 print_indexed (basereg
, p
, addr
, info
)
1223 disassemble_info
*info
;
1226 static char *const scales
[] = { "", ":2", ":4", ":8" };
1232 word
= NEXTWORD (p
);
1234 /* Generate the text for the index register.
1235 Where this will be output is not yet determined. */
1236 sprintf (buf
, "%s:%c%s",
1237 reg_names
[(word
>> 12) & 0xf],
1238 (word
& 0x800) ? 'l' : 'w',
1239 scales
[(word
>> 9) & 3]);
1241 /* Handle the 68000 style of indexing. */
1243 if ((word
& 0x100) == 0)
1245 base_disp
= word
& 0xff;
1246 if ((base_disp
& 0x80) != 0)
1250 print_base (basereg
, base_disp
, info
);
1251 (*info
->fprintf_func
) (info
->stream
, ",%s)", buf
);
1255 /* Handle the generalized kind. */
1256 /* First, compute the displacement to add to the base register. */
1268 switch ((word
>> 4) & 3)
1271 base_disp
= NEXTWORD (p
);
1274 base_disp
= NEXTLONG (p
);
1279 /* Handle single-level case (not indirect) */
1281 if ((word
& 7) == 0)
1283 print_base (basereg
, base_disp
, info
);
1285 (*info
->fprintf_func
) (info
->stream
, ",%s", buf
);
1286 (*info
->fprintf_func
) (info
->stream
, ")");
1290 /* Two level. Compute displacement to add after indirection. */
1296 outer_disp
= NEXTWORD (p
);
1299 outer_disp
= NEXTLONG (p
);
1302 print_base (basereg
, base_disp
, info
);
1303 if ((word
& 4) == 0 && buf
[0] != '\0')
1305 (*info
->fprintf_func
) (info
->stream
, ",%s", buf
);
1308 sprintf_vma (vmabuf
, outer_disp
);
1309 (*info
->fprintf_func
) (info
->stream
, ")@(%s", vmabuf
);
1311 (*info
->fprintf_func
) (info
->stream
, ",%s", buf
);
1312 (*info
->fprintf_func
) (info
->stream
, ")");
1317 /* Print a base register REGNO and displacement DISP, on INFO->STREAM.
1318 REGNO = -1 for pc, -2 for none (suppressed). */
1321 print_base (regno
, disp
, info
)
1324 disassemble_info
*info
;
1328 (*info
->fprintf_func
) (info
->stream
, "%%pc@(");
1329 (*info
->print_address_func
) (disp
, info
);
1336 (*info
->fprintf_func
) (info
->stream
, "@(");
1337 else if (regno
== -3)
1338 (*info
->fprintf_func
) (info
->stream
, "%%zpc@(");
1340 (*info
->fprintf_func
) (info
->stream
, "%s@(", reg_names
[regno
]);
1342 sprintf_vma (buf
, disp
);
1343 (*info
->fprintf_func
) (info
->stream
, "%s", buf
);