1 /* Print Motorola 68k instructions.
2 Copyright 1986, 87, 89, 91, 92, 93, 94, 95, 96, 97, 98, 1999
3 Free Software Foundation, Inc.
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.
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.
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. */
21 #include "floatformat.h"
22 #include <libiberty.h>
25 #include "opcode/m68k.h"
27 /* Local function prototypes */
30 fetch_data
PARAMS ((struct disassemble_info
*, bfd_byte
*));
33 dummy_print_address
PARAMS ((bfd_vma
, struct disassemble_info
*));
36 fetch_arg
PARAMS ((unsigned char *, int, int, disassemble_info
*));
39 print_base
PARAMS ((int, bfd_vma
, disassemble_info
*));
41 static unsigned char *
42 print_indexed
PARAMS ((int, unsigned char *, bfd_vma
, disassemble_info
*));
45 print_insn_arg
PARAMS ((const char *, unsigned char *, unsigned char *,
46 bfd_vma
, disassemble_info
*));
48 CONST
char * CONST fpcr_names
[] = {
49 "", "%fpiar", "%fpsr", "%fpiar/%fpsr", "%fpcr",
50 "%fpiar/%fpcr", "%fpsr/%fpcr", "%fpiar/%fpsr/%fpcr"};
52 static char *const reg_names
[] = {
53 "%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7",
54 "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%fp", "%sp",
57 /* Sign-extend an (unsigned char). */
59 #define COERCE_SIGNED_CHAR(ch) ((signed char)(ch))
61 #define COERCE_SIGNED_CHAR(ch) ((int)(((ch) ^ 0x80) & 0xFF) - 128)
64 /* Get a 1 byte signed integer. */
65 #define NEXTBYTE(p) (p += 2, FETCH_DATA (info, p), COERCE_SIGNED_CHAR(p[-1]))
67 /* Get a 2 byte signed integer. */
68 #define COERCE16(x) ((int) (((x) ^ 0x8000) - 0x8000))
70 (p += 2, FETCH_DATA (info, p), \
71 COERCE16 ((p[-2] << 8) + p[-1]))
73 /* Get a 4 byte signed integer. */
74 #define COERCE32(x) ((bfd_signed_vma) ((x) ^ 0x80000000) - 0x80000000)
76 (p += 4, FETCH_DATA (info, p), \
77 (COERCE32 ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])))
79 /* Get a 4 byte unsigned integer. */
80 #define NEXTULONG(p) \
81 (p += 4, FETCH_DATA (info, p), \
82 (unsigned int) ((((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1]))
84 /* Get a single precision float. */
85 #define NEXTSINGLE(val, p) \
86 (p += 4, FETCH_DATA (info, p), \
87 floatformat_to_double (&floatformat_ieee_single_big, (char *) p - 4, &val))
89 /* Get a double precision float. */
90 #define NEXTDOUBLE(val, p) \
91 (p += 8, FETCH_DATA (info, p), \
92 floatformat_to_double (&floatformat_ieee_double_big, (char *) p - 8, &val))
94 /* Get an extended precision float. */
95 #define NEXTEXTEND(val, p) \
96 (p += 12, FETCH_DATA (info, p), \
97 floatformat_to_double (&floatformat_m68881_ext, (char *) p - 12, &val))
99 /* Need a function to convert from packed to double
100 precision. Actually, it's easier to print a
101 packed number than a double anyway, so maybe
102 there should be a special case to handle this... */
103 #define NEXTPACKED(p) \
104 (p += 12, FETCH_DATA (info, p), 0.0)
107 /* Maximum length of an instruction. */
114 /* Points to first byte not fetched. */
115 bfd_byte
*max_fetched
;
116 bfd_byte the_buffer
[MAXLEN
];
121 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
122 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
124 #define FETCH_DATA(info, addr) \
125 ((addr) <= ((struct private *)(info->private_data))->max_fetched \
126 ? 1 : fetch_data ((info), (addr)))
129 fetch_data (info
, addr
)
130 struct disassemble_info
*info
;
134 struct private *priv
= (struct private *)info
->private_data
;
135 bfd_vma start
= priv
->insn_start
+ (priv
->max_fetched
- priv
->the_buffer
);
137 status
= (*info
->read_memory_func
) (start
,
139 addr
- priv
->max_fetched
,
143 (*info
->memory_error_func
) (status
, start
, info
);
144 longjmp (priv
->bailout
, 1);
147 priv
->max_fetched
= addr
;
151 /* This function is used to print to the bit-bucket. */
154 dummy_printer (FILE * file
, const char * format
, ...)
156 dummy_printer (file
) FILE *file
;
161 dummy_print_address (vma
, info
)
163 struct disassemble_info
*info
;
167 /* Print the m68k instruction at address MEMADDR in debugged memory,
168 on INFO->STREAM. Returns length of the instruction, in bytes. */
171 print_insn_m68k (memaddr
, info
)
173 disassemble_info
*info
;
176 register unsigned char *p
;
177 unsigned char *save_p
;
178 register const char *d
;
179 register unsigned long bestmask
;
180 const struct m68k_opcode
*best
= 0;
181 unsigned int arch_mask
;
183 bfd_byte
*buffer
= priv
.the_buffer
;
184 fprintf_ftype save_printer
= info
->fprintf_func
;
185 void (*save_print_address
) PARAMS((bfd_vma
, struct disassemble_info
*))
186 = info
->print_address_func
;
188 static int numopcodes
[16];
189 static const struct m68k_opcode
**opcodes
[16];
193 /* Speed up the matching by sorting the opcode table on the upper
194 four bits of the opcode. */
195 const struct m68k_opcode
**opc_pointer
[16];
197 /* First count how many opcodes are in each of the sixteen buckets. */
198 for (i
= 0; i
< m68k_numopcodes
; i
++)
199 numopcodes
[(m68k_opcodes
[i
].opcode
>> 28) & 15]++;
201 /* Then create a sorted table of pointers that point into the
203 opc_pointer
[0] = ((const struct m68k_opcode
**)
204 xmalloc (sizeof (struct m68k_opcode
*)
206 opcodes
[0] = opc_pointer
[0];
207 for (i
= 1; i
< 16; i
++)
209 opc_pointer
[i
] = opc_pointer
[i
- 1] + numopcodes
[i
- 1];
210 opcodes
[i
] = opc_pointer
[i
];
213 for (i
= 0; i
< m68k_numopcodes
; i
++)
214 *opc_pointer
[(m68k_opcodes
[i
].opcode
>> 28) & 15]++ = &m68k_opcodes
[i
];
218 info
->private_data
= (PTR
) &priv
;
219 /* Tell objdump to use two bytes per chunk and six bytes per line for
220 displaying raw data. */
221 info
->bytes_per_chunk
= 2;
222 info
->bytes_per_line
= 6;
223 info
->display_endian
= BFD_ENDIAN_BIG
;
224 priv
.max_fetched
= priv
.the_buffer
;
225 priv
.insn_start
= memaddr
;
226 if (setjmp (priv
.bailout
) != 0)
234 arch_mask
= (unsigned int) -1;
236 case bfd_mach_m68000
:
239 case bfd_mach_m68008
:
242 case bfd_mach_m68010
:
245 case bfd_mach_m68020
:
248 case bfd_mach_m68030
:
251 case bfd_mach_m68040
:
254 case bfd_mach_m68060
:
259 arch_mask
|= m68881
| m68851
;
262 FETCH_DATA (info
, buffer
+ 2);
263 major_opcode
= (buffer
[0] >> 4) & 15;
264 for (i
= 0; i
< numopcodes
[major_opcode
]; i
++)
266 const struct m68k_opcode
*opc
= opcodes
[major_opcode
][i
];
267 unsigned long opcode
= opc
->opcode
;
268 unsigned long match
= opc
->match
;
270 if (((0xff & buffer
[0] & (match
>> 24)) == (0xff & (opcode
>> 24)))
271 && ((0xff & buffer
[1] & (match
>> 16)) == (0xff & (opcode
>> 16)))
272 /* Only fetch the next two bytes if we need to. */
273 && (((0xffff & match
) == 0)
275 (FETCH_DATA (info
, buffer
+ 4)
276 && ((0xff & buffer
[2] & (match
>> 8)) == (0xff & (opcode
>> 8)))
277 && ((0xff & buffer
[3] & match
) == (0xff & opcode
)))
279 && (opc
->arch
& arch_mask
) != 0)
281 /* Don't use for printout the variants of divul and divsl
282 that have the same register number in two places.
283 The more general variants will match instead. */
284 for (d
= opc
->args
; *d
; d
+= 2)
288 /* Don't use for printout the variants of most floating
289 point coprocessor instructions which use the same
290 register number in two places, as above. */
292 for (d
= opc
->args
; *d
; d
+= 2)
296 /* Don't match fmovel with more than one register; wait for
300 for (d
= opc
->args
; *d
; d
+= 2)
302 if (d
[0] == 's' && d
[1] == '8')
306 val
= fetch_arg (buffer
, d
[1], 3, info
);
307 if ((val
& (val
- 1)) != 0)
313 if (*d
== '\0' && match
> bestmask
)
324 /* Point at first word of argument data,
325 and at descriptor for first argument. */
328 /* Figure out how long the fixed-size portion of the instruction is.
329 The only place this is stored in the opcode table is
330 in the arguments--look for arguments which specify fields in the 2nd
331 or 3rd words of the instruction. */
332 for (d
= best
->args
; *d
; d
+= 2)
334 /* I don't think it is necessary to be checking d[0] here; I suspect
335 all this could be moved to the case statement below. */
338 if (d
[1] == 'l' && p
- buffer
< 6)
340 else if (p
- buffer
< 4 && d
[1] != 'C' && d
[1] != '8' )
343 if ((d
[0] == 'L' || d
[0] == 'l') && d
[1] == 'w' && p
- buffer
< 4)
368 /* pflusha is an exceptions. It takes no arguments but is two words
369 long. Recognize it by looking at the lower 16 bits of the mask. */
370 if (p
- buffer
< 4 && (best
->match
& 0xFFFF) != 0)
373 /* lpstop is another exception. It takes a one word argument but is
376 && (best
->match
& 0xffff) == 0xffff
377 && best
->args
[0] == '#'
378 && best
->args
[1] == 'w')
380 /* Copy the one word argument into the usual location for a one
381 word argument, to simplify printing it. We can get away with
382 this because we know exactly what the second word is, and we
383 aren't going to print anything based on it. */
385 FETCH_DATA (info
, p
);
386 buffer
[2] = buffer
[4];
387 buffer
[3] = buffer
[5];
390 FETCH_DATA (info
, p
);
394 /* We can the operands twice. The first time we don't print anything,
395 but look for errors. */
398 info
->print_address_func
= dummy_print_address
;
399 info
->fprintf_func
= (fprintf_ftype
)dummy_printer
;
402 int eaten
= print_insn_arg (d
, buffer
, p
, memaddr
+ (p
- buffer
), info
);
405 else if (eaten
== -1)
409 (*info
->fprintf_func
)(info
->stream
,
410 /* xgettext:c-format */
411 _("<internal error in opcode table: %s %s>\n"),
419 info
->fprintf_func
= save_printer
;
420 info
->print_address_func
= save_print_address
;
424 (*info
->fprintf_func
) (info
->stream
, "%s", best
->name
);
427 (*info
->fprintf_func
) (info
->stream
, " ");
431 p
+= print_insn_arg (d
, buffer
, p
, memaddr
+ (p
- buffer
), info
);
433 if (*d
&& *(d
- 2) != 'I' && *d
!= 'k')
434 (*info
->fprintf_func
) (info
->stream
, ",");
439 /* Handle undefined instructions. */
440 info
->fprintf_func
= save_printer
;
441 info
->print_address_func
= save_print_address
;
442 (*info
->fprintf_func
) (info
->stream
, "0%o",
443 (buffer
[0] << 8) + buffer
[1]);
447 /* Returns number of bytes "eaten" by the operand, or
448 return -1 if an invalid operand was found, or -2 if
449 an opcode tabe error was found. */
452 print_insn_arg (d
, buffer
, p0
, addr
, info
)
454 unsigned char *buffer
;
456 bfd_vma addr
; /* PC for this arg to be relative to */
457 disassemble_info
*info
;
459 register int val
= 0;
460 register int place
= d
[1];
461 register unsigned char *p
= p0
;
463 register CONST
char *regname
;
464 register unsigned char *p1
;
472 case 'c': /* cache identifier */
474 static char *const cacheFieldName
[] = { "nc", "dc", "ic", "bc" };
475 val
= fetch_arg (buffer
, place
, 2, info
);
476 (*info
->fprintf_func
) (info
->stream
, cacheFieldName
[val
]);
480 case 'a': /* address register indirect only. Cf. case '+'. */
482 (*info
->fprintf_func
)
485 reg_names
[fetch_arg (buffer
, place
, 3, info
) + 8]);
489 case '_': /* 32-bit absolute address for move16. */
491 uval
= NEXTULONG (p
);
492 (*info
->print_address_func
) (uval
, info
);
497 (*info
->fprintf_func
) (info
->stream
, "%%ccr");
501 (*info
->fprintf_func
) (info
->stream
, "%%sr");
505 (*info
->fprintf_func
) (info
->stream
, "%%usp");
509 (*info
->fprintf_func
) (info
->stream
, "%%acc");
513 (*info
->fprintf_func
) (info
->stream
, "%%macsr");
517 (*info
->fprintf_func
) (info
->stream
, "%%mask");
522 static const struct { char *name
; int value
; } names
[]
523 = {{"%sfc", 0x000}, {"%dfc", 0x001}, {"%cacr", 0x002},
524 {"%tc", 0x003}, {"%itt0",0x004}, {"%itt1", 0x005},
525 {"%dtt0",0x006}, {"%dtt1",0x007}, {"%buscr",0x008},
526 {"%usp", 0x800}, {"%vbr", 0x801}, {"%caar", 0x802},
527 {"%msp", 0x803}, {"%isp", 0x804},
529 /* Should we be calling this psr like we do in case 'Y'? */
532 {"%urp", 0x806}, {"%srp", 0x807}, {"%pcr", 0x808}};
534 val
= fetch_arg (buffer
, place
, 12, info
);
535 for (regno
= sizeof names
/ sizeof names
[0] - 1; regno
>= 0; regno
--)
536 if (names
[regno
].value
== val
)
538 (*info
->fprintf_func
) (info
->stream
, "%s", names
[regno
].name
);
542 (*info
->fprintf_func
) (info
->stream
, "%d", val
);
547 val
= fetch_arg (buffer
, place
, 3, info
);
548 /* 0 means 8, except for the bkpt instruction... */
549 if (val
== 0 && d
[1] != 's')
551 (*info
->fprintf_func
) (info
->stream
, "#%d", val
);
557 static char *const scalefactor_name
[] = { "<<", ">>" };
558 val
= fetch_arg (buffer
, place
, 1, info
);
559 (*info
->fprintf_func
) (info
->stream
, scalefactor_name
[val
]);
563 val
= fetch_arg (buffer
, place
, 8, info
);
566 (*info
->fprintf_func
) (info
->stream
, "#%d", val
);
571 val
= fetch_arg (buffer
, place
, 4, info
);
572 (*info
->fprintf_func
) (info
->stream
, "#%d", val
);
576 (*info
->fprintf_func
) (info
->stream
, "%s",
577 reg_names
[fetch_arg (buffer
, place
, 3, info
)]);
581 (*info
->fprintf_func
)
583 reg_names
[fetch_arg (buffer
, place
, 3, info
) + 010]);
587 (*info
->fprintf_func
)
589 reg_names
[fetch_arg (buffer
, place
, 4, info
)]);
593 regno
= fetch_arg (buffer
, place
, 4, info
);
595 (*info
->fprintf_func
) (info
->stream
, "%s@", reg_names
[regno
]);
597 (*info
->fprintf_func
) (info
->stream
, "@(%s)", reg_names
[regno
]);
601 (*info
->fprintf_func
)
602 (info
->stream
, "%%fp%d",
603 fetch_arg (buffer
, place
, 3, info
));
607 val
= fetch_arg (buffer
, place
, 6, info
);
609 (*info
->fprintf_func
) (info
->stream
, "%s", reg_names
[val
& 7]);
611 (*info
->fprintf_func
) (info
->stream
, "%d", val
);
615 (*info
->fprintf_func
)
616 (info
->stream
, "%s@+",
617 reg_names
[fetch_arg (buffer
, place
, 3, info
) + 8]);
621 (*info
->fprintf_func
)
622 (info
->stream
, "%s@-",
623 reg_names
[fetch_arg (buffer
, place
, 3, info
) + 8]);
628 (*info
->fprintf_func
)
629 (info
->stream
, "{%s}",
630 reg_names
[fetch_arg (buffer
, place
, 3, info
)]);
631 else if (place
== 'C')
633 val
= fetch_arg (buffer
, place
, 7, info
);
634 if ( val
> 63 ) /* This is a signed constant. */
636 (*info
->fprintf_func
) (info
->stream
, "{#%d}", val
);
644 p1
= buffer
+ (*d
== '#' ? 2 : 4);
646 val
= fetch_arg (buffer
, place
, 4, info
);
647 else if (place
== 'C')
648 val
= fetch_arg (buffer
, place
, 7, info
);
649 else if (place
== '8')
650 val
= fetch_arg (buffer
, place
, 3, info
);
651 else if (place
== '3')
652 val
= fetch_arg (buffer
, place
, 8, info
);
653 else if (place
== 'b')
655 else if (place
== 'w' || place
== 'W')
657 else if (place
== 'l')
661 (*info
->fprintf_func
) (info
->stream
, "#%d", val
);
667 else if (place
== 'B')
668 disp
= COERCE_SIGNED_CHAR(buffer
[1]);
669 else if (place
== 'w' || place
== 'W')
671 else if (place
== 'l' || place
== 'L' || place
== 'C')
673 else if (place
== 'g')
675 disp
= NEXTBYTE (buffer
);
681 else if (place
== 'c')
683 if (buffer
[1] & 0x40) /* If bit six is one, long offset */
691 (*info
->print_address_func
) (addr
+ disp
, info
);
696 (*info
->fprintf_func
)
697 (info
->stream
, "%s@(%d)",
698 reg_names
[fetch_arg (buffer
, place
, 3, info
) + 8], val
);
702 (*info
->fprintf_func
) (info
->stream
, "%s",
703 fpcr_names
[fetch_arg (buffer
, place
, 3, info
)]);
707 /* Get coprocessor ID... */
708 val
= fetch_arg (buffer
, 'd', 3, info
);
710 if (val
!= 1) /* Unusual coprocessor ID? */
711 (*info
->fprintf_func
) (info
->stream
, "(cpid=%d) ", val
);
736 val
= fetch_arg (buffer
, 'x', 6, info
);
737 val
= ((val
& 7) << 3) + ((val
>> 3) & 7);
740 val
= fetch_arg (buffer
, 's', 6, info
);
742 /* Get register number assuming address register. */
743 regno
= (val
& 7) + 8;
744 regname
= reg_names
[regno
];
748 (*info
->fprintf_func
) (info
->stream
, "%s", reg_names
[val
]);
752 (*info
->fprintf_func
) (info
->stream
, "%s", regname
);
756 (*info
->fprintf_func
) (info
->stream
, "%s@", regname
);
760 (*info
->fprintf_func
) (info
->stream
, "%s@+", regname
);
764 (*info
->fprintf_func
) (info
->stream
, "%s@-", regname
);
769 (*info
->fprintf_func
) (info
->stream
, "%s@(%d)", regname
, val
);
773 p
= print_indexed (regno
, p
, addr
, info
);
781 (*info
->print_address_func
) (val
, info
);
785 uval
= NEXTULONG (p
);
786 (*info
->print_address_func
) (uval
, info
);
791 (*info
->fprintf_func
) (info
->stream
, "%%pc@(");
792 (*info
->print_address_func
) (addr
+ val
, info
);
793 (*info
->fprintf_func
) (info
->stream
, ")");
797 p
= print_indexed (-1, p
, addr
, info
);
801 flt_p
= 1; /* Assume it's a float... */
820 NEXTSINGLE(flval
, p
);
824 NEXTDOUBLE(flval
, p
);
828 NEXTEXTEND(flval
, p
);
832 flval
= NEXTPACKED(p
);
838 if ( flt_p
) /* Print a float? */
839 (*info
->fprintf_func
) (info
->stream
, "#%g", flval
);
841 (*info
->fprintf_func
) (info
->stream
, "#%d", val
);
857 /* Move the pointer ahead if this point is farther ahead
862 (*info
->fprintf_func
) (info
->stream
, "#0");
867 register int newval
= 0;
868 for (regno
= 0; regno
< 16; ++regno
)
869 if (val
& (0x8000 >> regno
))
870 newval
|= 1 << regno
;
875 for (regno
= 0; regno
< 16; ++regno
)
876 if (val
& (1 << regno
))
880 (*info
->fprintf_func
) (info
->stream
, "/");
882 (*info
->fprintf_func
) (info
->stream
, "%s", reg_names
[regno
]);
884 while (val
& (1 << (regno
+ 1)))
886 if (regno
> first_regno
)
887 (*info
->fprintf_func
) (info
->stream
, "-%s",
891 else if (place
== '3')
895 val
= fetch_arg (buffer
, place
, 8, info
);
898 (*info
->fprintf_func
) (info
->stream
, "#0");
903 register int newval
= 0;
904 for (regno
= 0; regno
< 8; ++regno
)
905 if (val
& (0x80 >> regno
))
906 newval
|= 1 << regno
;
911 for (regno
= 0; regno
< 8; ++regno
)
912 if (val
& (1 << regno
))
916 (*info
->fprintf_func
) (info
->stream
, "/");
918 (*info
->fprintf_func
) (info
->stream
, "%%fp%d", regno
);
920 while (val
& (1 << (regno
+ 1)))
922 if (regno
> first_regno
)
923 (*info
->fprintf_func
) (info
->stream
, "-%%fp%d", regno
);
926 else if (place
== '8')
928 /* fmoveml for FP status registers */
929 (*info
->fprintf_func
) (info
->stream
, "%s",
930 fpcr_names
[fetch_arg (buffer
, place
, 3,
947 int val
= fetch_arg (buffer
, place
, 5, info
);
951 case 2: name
= "%tt0"; break;
952 case 3: name
= "%tt1"; break;
953 case 0x10: name
= "%tc"; break;
954 case 0x11: name
= "%drp"; break;
955 case 0x12: name
= "%srp"; break;
956 case 0x13: name
= "%crp"; break;
957 case 0x14: name
= "%cal"; break;
958 case 0x15: name
= "%val"; break;
959 case 0x16: name
= "%scc"; break;
960 case 0x17: name
= "%ac"; break;
961 case 0x18: name
= "%psr"; break;
962 case 0x19: name
= "%pcsr"; break;
966 int break_reg
= ((buffer
[3] >> 2) & 7);
967 (*info
->fprintf_func
)
968 (info
->stream
, val
== 0x1c ? "%%bad%d" : "%%bac%d",
973 (*info
->fprintf_func
) (info
->stream
, "<mmu register %d>", val
);
976 (*info
->fprintf_func
) (info
->stream
, "%s", name
);
982 int fc
= fetch_arg (buffer
, place
, 5, info
);
984 (*info
->fprintf_func
) (info
->stream
, "%%dfc");
986 (*info
->fprintf_func
) (info
->stream
, "%%sfc");
988 /* xgettext:c-format */
989 (*info
->fprintf_func
) (info
->stream
, _("<function code %d>"), fc
);
994 (*info
->fprintf_func
) (info
->stream
, "%%val");
999 int level
= fetch_arg (buffer
, place
, 3, info
);
1000 (*info
->fprintf_func
) (info
->stream
, "%d", level
);
1007 int reg
= fetch_arg (buffer
, place
, 5, info
);
1014 (*info
->fprintf_func
) (info
->stream
, "%s%s",
1016 is_upper
? "u" : "l");
1027 /* Fetch BITS bits from a position in the instruction specified by CODE.
1028 CODE is a "place to put an argument", or 'x' for a destination
1029 that is a general address (mode and register).
1030 BUFFER contains the instruction. */
1033 fetch_arg (buffer
, code
, bits
, info
)
1034 unsigned char *buffer
;
1037 disassemble_info
*info
;
1039 register int val
= 0;
1046 case 'd': /* Destination, for register or quick. */
1047 val
= (buffer
[0] << 8) + buffer
[1];
1051 case 'x': /* Destination, for general arg */
1052 val
= (buffer
[0] << 8) + buffer
[1];
1057 FETCH_DATA (info
, buffer
+ 3);
1058 val
= (buffer
[3] >> 4);
1062 FETCH_DATA (info
, buffer
+ 3);
1067 FETCH_DATA (info
, buffer
+ 3);
1068 val
= (buffer
[2] << 8) + buffer
[3];
1073 FETCH_DATA (info
, buffer
+ 3);
1074 val
= (buffer
[2] << 8) + buffer
[3];
1080 FETCH_DATA (info
, buffer
+ 3);
1081 val
= (buffer
[2] << 8) + buffer
[3];
1085 FETCH_DATA (info
, buffer
+ 5);
1086 val
= (buffer
[4] << 8) + buffer
[5];
1091 FETCH_DATA (info
, buffer
+ 5);
1092 val
= (buffer
[4] << 8) + buffer
[5];
1097 FETCH_DATA (info
, buffer
+ 5);
1098 val
= (buffer
[4] << 8) + buffer
[5];
1102 FETCH_DATA (info
, buffer
+ 3);
1103 val
= (buffer
[2] << 8) + buffer
[3];
1108 FETCH_DATA (info
, buffer
+ 3);
1109 val
= (buffer
[2] << 8) + buffer
[3];
1114 FETCH_DATA (info
, buffer
+ 3);
1115 val
= (buffer
[2] << 8) + buffer
[3];
1120 val
= (buffer
[1] >> 6);
1124 val
= (buffer
[1] & 0x40 ? 0x8 : 0)
1125 | ((buffer
[0] >> 1) & 0x7)
1126 | (buffer
[3] & 0x80 ? 0x10 : 0);
1130 val
= (buffer
[1] & 0x40 ? 0x8 : 0) | ((buffer
[0] >> 1) & 0x7);
1134 val
= (buffer
[2] >> 4) | (buffer
[3] & 0x80 ? 0x10 : 0);
1138 val
= buffer
[1] | (buffer
[3] & 0x40 ? 0x10 : 0);
1142 val
= buffer
[3] | (buffer
[3] & 0x40 ? 0x10 : 0);
1146 val
= buffer
[2] >> 2;
1178 /* Print an indexed argument. The base register is BASEREG (-1 for pc).
1179 P points to extension word, in buffer.
1180 ADDR is the nominal core address of that extension word. */
1182 static unsigned char *
1183 print_indexed (basereg
, p
, addr
, info
)
1187 disassemble_info
*info
;
1190 static char *const scales
[] = {"", ":2", ":4", ":8"};
1196 word
= NEXTWORD (p
);
1198 /* Generate the text for the index register.
1199 Where this will be output is not yet determined. */
1200 sprintf (buf
, "%s:%c%s",
1201 reg_names
[(word
>> 12) & 0xf],
1202 (word
& 0x800) ? 'l' : 'w',
1203 scales
[(word
>> 9) & 3]);
1205 /* Handle the 68000 style of indexing. */
1207 if ((word
& 0x100) == 0)
1209 base_disp
= word
& 0xff;
1210 if ((base_disp
& 0x80) != 0)
1214 print_base (basereg
, base_disp
, info
);
1215 (*info
->fprintf_func
) (info
->stream
, ",%s)", buf
);
1219 /* Handle the generalized kind. */
1220 /* First, compute the displacement to add to the base register. */
1232 switch ((word
>> 4) & 3)
1235 base_disp
= NEXTWORD (p
);
1238 base_disp
= NEXTLONG (p
);
1243 /* Handle single-level case (not indirect) */
1245 if ((word
& 7) == 0)
1247 print_base (basereg
, base_disp
, info
);
1249 (*info
->fprintf_func
) (info
->stream
, ",%s", buf
);
1250 (*info
->fprintf_func
) (info
->stream
, ")");
1254 /* Two level. Compute displacement to add after indirection. */
1260 outer_disp
= NEXTWORD (p
);
1263 outer_disp
= NEXTLONG (p
);
1266 print_base (basereg
, base_disp
, info
);
1267 if ((word
& 4) == 0 && buf
[0] != '\0')
1269 (*info
->fprintf_func
) (info
->stream
, ",%s", buf
);
1272 sprintf_vma (vmabuf
, outer_disp
);
1273 (*info
->fprintf_func
) (info
->stream
, ")@(%s", vmabuf
);
1275 (*info
->fprintf_func
) (info
->stream
, ",%s", buf
);
1276 (*info
->fprintf_func
) (info
->stream
, ")");
1281 /* Print a base register REGNO and displacement DISP, on INFO->STREAM.
1282 REGNO = -1 for pc, -2 for none (suppressed). */
1285 print_base (regno
, disp
, info
)
1288 disassemble_info
*info
;
1292 (*info
->fprintf_func
) (info
->stream
, "%%pc@(");
1293 (*info
->print_address_func
) (disp
, info
);
1300 (*info
->fprintf_func
) (info
->stream
, "@(");
1301 else if (regno
== -3)
1302 (*info
->fprintf_func
) (info
->stream
, "%%zpc@(");
1304 (*info
->fprintf_func
) (info
->stream
, "%s@(", reg_names
[regno
]);
1306 sprintf_vma (buf
, disp
);
1307 (*info
->fprintf_func
) (info
->stream
, "%s", buf
);