1 /* Print Motorola 68k instructions.
2 Copyright (C) 1986-2024 Free Software Foundation, Inc.
4 This file is part of the GNU opcodes library.
6 This library 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 3, or (at your option)
11 It is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 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., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
22 #include "disassemble.h"
23 #include "floatformat.h"
24 #include "libiberty.h"
27 #include "opcode/m68k.h"
29 /* Local function prototypes. */
31 const char * const fpcr_names
[] =
33 "", "%fpiar", "%fpsr", "%fpiar/%fpsr", "%fpcr",
34 "%fpiar/%fpcr", "%fpsr/%fpcr", "%fpiar/%fpsr/%fpcr"
37 static char *const reg_names
[] =
39 "%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7",
40 "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%fp", "%sp",
44 /* Name of register halves for MAC/EMAC.
45 Seperate from reg_names since 'spu', 'fpl' look weird. */
46 static char *const reg_half_names
[] =
48 "%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7",
49 "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%a6", "%a7",
53 /* Sign-extend an (unsigned char). */
55 #define COERCE_SIGNED_CHAR(ch) ((signed char) (ch))
57 #define COERCE_SIGNED_CHAR(ch) ((int) (((ch) ^ 0x80) & 0xFF) - 128)
60 /* Error code of print_insn_arg's return value. */
62 enum print_insn_arg_error
64 /* An invalid operand is found. */
65 PRINT_INSN_ARG_INVALID_OPERAND
= -1,
67 /* An opcode table error. */
68 PRINT_INSN_ARG_INVALID_OP_TABLE
= -2,
71 PRINT_INSN_ARG_MEMORY_ERROR
= -3,
74 /* Get a 1 byte signed integer. */
75 #define NEXTBYTE(p, val) \
79 if (!FETCH_DATA (info, p)) \
80 return PRINT_INSN_ARG_MEMORY_ERROR; \
81 val = COERCE_SIGNED_CHAR (p[-1]); \
85 /* Get a 2 byte signed integer. */
86 #define COERCE16(x) ((int) (((x) ^ 0x8000) - 0x8000))
88 #define NEXTWORD(p, val, ret_val) \
92 if (!FETCH_DATA (info, p)) \
94 val = COERCE16 ((p[-2] << 8) + p[-1]); \
98 /* Get a 4 byte signed integer. */
99 #define COERCE32(x) (((bfd_vma) (x) ^ 0x80000000) - 0x80000000)
101 #define NEXTLONG(p, val, ret_val) \
105 if (!FETCH_DATA (info, p)) \
107 val = COERCE32 (((((((unsigned) p[-4] << 8) + p[-3]) << 8) \
108 + p[-2]) << 8) + p[-1]); \
112 /* Get a 4 byte unsigned integer. */
113 #define NEXTULONG(p, val) \
117 if (!FETCH_DATA (info, p)) \
118 return PRINT_INSN_ARG_MEMORY_ERROR; \
119 val = (((((((unsigned) p[-4] << 8) + p[-3]) << 8) \
120 + p[-2]) << 8) + p[-1]); \
124 /* Get a single precision float. */
125 #define NEXTSINGLE(val, p) \
129 if (!FETCH_DATA (info, p)) \
130 return PRINT_INSN_ARG_MEMORY_ERROR; \
131 floatformat_to_double (& floatformat_ieee_single_big, \
132 (char *) p - 4, & val); \
136 /* Get a double precision float. */
137 #define NEXTDOUBLE(val, p) \
141 if (!FETCH_DATA (info, p)) \
142 return PRINT_INSN_ARG_MEMORY_ERROR; \
143 floatformat_to_double (& floatformat_ieee_double_big, \
144 (char *) p - 8, & val); \
148 /* Get an extended precision float. */
149 #define NEXTEXTEND(val, p) \
153 if (!FETCH_DATA (info, p)) \
154 return PRINT_INSN_ARG_MEMORY_ERROR; \
155 floatformat_to_double (& floatformat_m68881_ext, \
156 (char *) p - 12, & val); \
160 /* Need a function to convert from packed to double
161 precision. Actually, it's easier to print a
162 packed number than a double anyway, so maybe
163 there should be a special case to handle this... */
164 #define NEXTPACKED(p, val) \
168 if (!FETCH_DATA (info, p)) \
169 return PRINT_INSN_ARG_MEMORY_ERROR; \
175 /* Maximum length of an instruction. */
180 /* Points to first byte not fetched. */
181 bfd_byte
*max_fetched
;
182 bfd_byte the_buffer
[MAXLEN
];
186 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
187 to ADDR (exclusive) are valid. Returns 1 for success, 0 on memory
189 #define FETCH_DATA(info, addr) \
190 ((addr) <= ((struct private *) (info->private_data))->max_fetched \
191 ? 1 : fetch_data ((info), (addr)))
194 fetch_data (struct disassemble_info
*info
, bfd_byte
*addr
)
197 struct private *priv
= (struct private *)info
->private_data
;
198 bfd_vma start
= priv
->insn_start
+ (priv
->max_fetched
- priv
->the_buffer
);
200 status
= (*info
->read_memory_func
) (start
,
202 addr
- priv
->max_fetched
,
206 (*info
->memory_error_func
) (status
, start
, info
);
210 priv
->max_fetched
= addr
;
214 /* This function is used to print to the bit-bucket. */
216 dummy_printer (void *file ATTRIBUTE_UNUSED
,
217 enum disassembler_style style ATTRIBUTE_UNUSED
,
218 const char *format ATTRIBUTE_UNUSED
,
225 dummy_print_address (bfd_vma vma ATTRIBUTE_UNUSED
,
226 struct disassemble_info
*info ATTRIBUTE_UNUSED
)
230 /* Fetch BITS bits from a position in the instruction specified by CODE.
231 CODE is a "place to put an argument", or 'x' for a destination
232 that is a general address (mode and register).
233 BUFFER contains the instruction.
234 Returns -1 on failure. */
237 fetch_arg (unsigned char *buffer
,
240 disassemble_info
*info
)
246 case '/': /* MAC/EMAC mask bit. */
247 val
= buffer
[3] >> 5;
250 case 'G': /* EMAC ACC load. */
251 val
= ((buffer
[3] >> 3) & 0x2) | ((~buffer
[1] >> 7) & 0x1);
254 case 'H': /* EMAC ACC !load. */
255 val
= ((buffer
[3] >> 3) & 0x2) | ((buffer
[1] >> 7) & 0x1);
258 case ']': /* EMAC ACCEXT bit. */
259 val
= buffer
[0] >> 2;
262 case 'I': /* MAC/EMAC scale factor. */
263 val
= buffer
[2] >> 1;
266 case 'F': /* EMAC ACCx. */
267 val
= buffer
[0] >> 1;
278 case 'd': /* Destination, for register or quick. */
279 val
= (buffer
[0] << 8) + buffer
[1];
283 case 'x': /* Destination, for general arg. */
284 val
= (buffer
[0] << 8) + buffer
[1];
289 if (! FETCH_DATA (info
, buffer
+ 3))
291 val
= (buffer
[3] >> 4);
295 if (! FETCH_DATA (info
, buffer
+ 3))
301 if (! FETCH_DATA (info
, buffer
+ 3))
303 val
= (buffer
[2] << 8) + buffer
[3];
308 if (! FETCH_DATA (info
, buffer
+ 3))
310 val
= (buffer
[2] << 8) + buffer
[3];
316 if (! FETCH_DATA (info
, buffer
+ 3))
318 val
= (buffer
[2] << 8) + buffer
[3];
322 if (! FETCH_DATA (info
, buffer
+ 5))
324 val
= (buffer
[4] << 8) + buffer
[5];
329 if (! FETCH_DATA (info
, buffer
+ 5))
331 val
= (buffer
[4] << 8) + buffer
[5];
336 if (! FETCH_DATA (info
, buffer
+ 5))
338 val
= (buffer
[4] << 8) + buffer
[5];
342 if (! FETCH_DATA (info
, buffer
+ 3))
344 val
= (buffer
[2] << 8) + buffer
[3];
349 if (! FETCH_DATA (info
, buffer
+ 3))
351 val
= (buffer
[2] << 8) + buffer
[3];
356 if (! FETCH_DATA (info
, buffer
+ 3))
358 val
= (buffer
[2] << 8) + buffer
[3];
363 val
= (buffer
[1] >> 6);
367 if (! FETCH_DATA (info
, buffer
+ 3))
369 val
= (buffer
[2] >> 1);
373 val
= (buffer
[1] & 0x40 ? 0x8 : 0)
374 | ((buffer
[0] >> 1) & 0x7)
375 | (buffer
[3] & 0x80 ? 0x10 : 0);
379 val
= (buffer
[1] & 0x40 ? 0x8 : 0) | ((buffer
[0] >> 1) & 0x7);
383 val
= (buffer
[2] >> 4) | (buffer
[3] & 0x80 ? 0x10 : 0);
387 val
= (buffer
[1] & 0xf) | (buffer
[3] & 0x40 ? 0x10 : 0);
391 val
= (buffer
[3] & 0xf) | (buffer
[3] & 0x40 ? 0x10 : 0);
395 val
= buffer
[2] >> 2;
402 /* bits is never too big. */
403 return val
& ((1 << bits
) - 1);
406 /* Check if an EA is valid for a particular code. This is required
407 for the EMAC instructions since the type of source address determines
408 if it is a EMAC-load instruciton if the EA is mode 2-5, otherwise it
409 is a non-load EMAC instruction and the bits mean register Ry.
410 A similar case exists for the movem instructions where the register
411 mask is interpreted differently for different EAs. */
414 m68k_valid_ea (char code
, int val
)
417 #define M(n0,n1,n2,n3,n4,n5,n6,n70,n71,n72,n73,n74) \
418 (n0 | n1 << 1 | n2 << 2 | n3 << 3 | n4 << 4 | n5 << 5 | n6 << 6 \
419 | n70 << 7 | n71 << 8 | n72 << 9 | n73 << 10 | n74 << 11)
424 mask
= M (1,1,1,1,1,1,1,1,1,1,1,1);
427 mask
= M (0,0,1,1,1,1,1,1,1,0,0,0);
430 mask
= M (1,1,1,1,1,1,1,1,1,0,0,0);
433 mask
= M (1,0,1,1,1,1,1,1,1,1,1,1);
436 mask
= M (1,0,1,1,1,1,1,1,1,1,1,0);
439 mask
= M (0,0,1,0,0,1,1,1,1,1,1,0);
442 mask
= M (0,0,1,0,0,1,1,1,1,0,0,0);
445 mask
= M (1,0,1,1,1,1,1,1,1,0,0,0);
448 mask
= M (1,0,1,0,0,1,1,1,1,0,0,0);
451 mask
= M (1,0,1,0,0,1,1,1,1,1,1,0);
454 mask
= M (0,0,1,0,0,1,1,1,1,1,1,0);
457 mask
= M (0,0,1,0,1,1,1,1,1,0,0,0);
460 mask
= M (0,0,1,1,0,1,1,1,1,1,1,0);
463 mask
= M (1,1,1,1,1,0,0,0,0,0,0,0);
466 mask
= M (0,0,0,0,0,1,0,0,0,1,0,0);
469 mask
= M (0,0,0,0,0,0,1,1,1,0,1,1);
472 mask
= M (1,1,1,1,1,1,0,0,0,0,0,0);
475 mask
= M (1,0,1,1,1,1,0,0,0,0,0,0);
478 mask
= M (1,0,1,1,1,1,0,1,1,0,0,0);
481 mask
= M (1,0,1,1,1,1,0,0,0,1,0,0);
484 mask
= M (0,0,1,1,1,1,0,0,0,1,0,0);
487 mask
= M (0,0,1,0,0,1,0,0,0,0,0,0);
490 mask
= M (0,0,1,0,0,1,0,0,0,1,0,0);
493 mask
= M (0,0,1,1,1,1,0,0,0,0,0,0);
500 mode
= (val
>> 3) & 7;
503 return (mask
& (1 << mode
)) != 0;
506 /* Print a base register REGNO and displacement DISP, on INFO->STREAM.
507 REGNO = -1 for pc, -2 for none (suppressed). */
510 print_base (int regno
, bfd_vma disp
, disassemble_info
*info
)
514 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
, "%%pc");
515 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, "@(");
516 (*info
->print_address_func
) (disp
, info
);
521 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
523 else if (regno
!= -2)
524 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
525 "%s", reg_names
[regno
]);
526 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, "@(");
527 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_immediate
,
528 "%" PRIx64
, (uint64_t) disp
);
532 /* Print the index register of an indexed argument, as encoded in the
536 print_index_register (int ext
, disassemble_info
*info
)
538 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
539 "%s", reg_names
[(ext
>> 12) & 0xf]);
540 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
,
541 ":%c", ext
& 0x800 ? 'l' : 'w');
544 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, ":");
545 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_immediate
,
546 "%d", 1 << ((ext
>> 9) & 3));
550 /* Print an indexed argument. The base register is BASEREG (-1 for pc).
551 P points to extension word, in buffer.
552 ADDR is the nominal core address of that extension word.
553 Returns NULL upon error. */
555 static unsigned char *
556 print_indexed (int basereg
,
559 disassemble_info
*info
)
564 bool print_index
= true;
566 NEXTWORD (p
, word
, NULL
);
568 /* Handle the 68000 style of indexing. */
570 if ((word
& 0x100) == 0)
572 base_disp
= word
& 0xff;
573 if ((base_disp
& 0x80) != 0)
577 print_base (basereg
, base_disp
, info
);
578 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, ",");
579 print_index_register (word
, info
);
580 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, ")");
584 /* Handle the generalized kind. */
585 /* First, compute the displacement to add to the base register. */
596 switch ((word
>> 4) & 3)
599 NEXTWORD (p
, base_disp
, NULL
);
602 NEXTLONG (p
, base_disp
, NULL
);
607 /* Handle single-level case (not indirect). */
610 print_base (basereg
, base_disp
, info
);
613 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, ",");
614 print_index_register (word
, info
);
616 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, ")");
620 /* Two level. Compute displacement to add after indirection. */
625 NEXTWORD (p
, outer_disp
, NULL
);
628 NEXTLONG (p
, outer_disp
, NULL
);
631 print_base (basereg
, base_disp
, info
);
632 if ((word
& 4) == 0 && print_index
)
634 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, ",");
635 print_index_register (word
, info
);
638 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
,
640 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_address_offset
,
641 "%" PRIx64
, (uint64_t) outer_disp
);
644 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, ",");
645 print_index_register (word
, info
);
647 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, ")");
652 #define FETCH_ARG(size, val) \
655 val = fetch_arg (buffer, place, size, info); \
657 return PRINT_INSN_ARG_MEMORY_ERROR; \
661 /* Returns number of bytes "eaten" by the operand, or
662 return enum print_insn_arg_error. ADDR is the pc for this arg to be
666 print_insn_arg (const char *d
,
667 unsigned char *buffer
,
670 disassemble_info
*info
)
674 unsigned char *p
= p0
;
685 case 'c': /* Cache identifier. */
687 static char *const cacheFieldName
[] = { "nc", "dc", "ic", "bc" };
689 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_sub_mnemonic
,
690 "%s", cacheFieldName
[val
]);
694 case 'a': /* Address register indirect only. Cf. case '+'. */
697 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
, "%s",
699 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, "@");
703 case '_': /* 32-bit absolute address for move16. */
706 (*info
->print_address_func
) (uval
, info
);
711 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
, "%%ccr");
715 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
, "%%sr");
719 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
, "%%usp");
723 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
, "%%acc");
727 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
, "%%macsr");
731 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
, "%%mask");
736 /* FIXME: There's a problem here, different m68k processors call the
737 same address different names. The tables below try to get it right
738 using info->mach, but only for v4e. */
739 struct regname
{ char * name
; int value
; };
740 static const struct regname names
[] =
742 {"%sfc", 0x000}, {"%dfc", 0x001}, {"%cacr", 0x002},
743 {"%tc", 0x003}, {"%itt0",0x004}, {"%itt1", 0x005},
744 {"%dtt0",0x006}, {"%dtt1",0x007}, {"%buscr",0x008},
745 {"%rgpiobar", 0x009}, {"%acr4",0x00c},
746 {"%acr5",0x00d}, {"%acr6",0x00e}, {"%acr7", 0x00f},
747 {"%usp", 0x800}, {"%vbr", 0x801}, {"%caar", 0x802},
748 {"%msp", 0x803}, {"%isp", 0x804},
750 /* Reg c04 is sometimes called flashbar or rambar.
751 Reg c05 is also sometimes called rambar. */
752 {"%rambar0", 0xc04}, {"%rambar1", 0xc05},
754 /* reg c0e is sometimes called mbar2 or secmbar.
755 reg c0f is sometimes called mbar. */
756 {"%mbar0", 0xc0e}, {"%mbar1", 0xc0f},
758 /* Should we be calling this psr like we do in case 'Y'? */
761 {"%urp", 0x806}, {"%srp", 0x807}, {"%pcr", 0x808},
763 /* Fido added these. */
764 {"%cac", 0xffe}, {"%mbo", 0xfff}
766 /* Alternate names for v4e (MCF5407/5445x/MCF547x/MCF548x), at least. */
767 static const struct regname names_v4e
[] =
769 {"%asid",0x003}, {"%acr0",0x004}, {"%acr1",0x005},
770 {"%acr2",0x006}, {"%acr3",0x007}, {"%mmubar",0x008},
772 unsigned int arch_mask
;
774 arch_mask
= bfd_m68k_mach_to_features (info
->mach
);
776 if (arch_mask
& (mcfisa_b
| mcfisa_c
))
778 for (regno
= ARRAY_SIZE (names_v4e
); --regno
>= 0;)
779 if (names_v4e
[regno
].value
== val
)
781 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
782 "%s", names_v4e
[regno
].name
);
788 for (regno
= ARRAY_SIZE (names
) - 1; regno
>= 0; regno
--)
789 if (names
[regno
].value
== val
)
791 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
792 "%s", names
[regno
].name
);
796 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, "0x%x", val
);
802 /* 0 means 8, except for the bkpt instruction... */
803 if (val
== 0 && d
[1] != 's')
805 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_immediate
,
814 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_immediate
,
820 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_immediate
,
826 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_immediate
,
833 static char *const scalefactor_name
[] = { "<<", ">>" };
836 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_sub_mnemonic
,
837 "%s", scalefactor_name
[val
]);
844 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_immediate
,
851 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_immediate
,
857 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
858 "%s", reg_names
[val
]);
863 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
864 "%s", reg_names
[val
+ 010]);
869 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
870 "%s", reg_names
[val
]);
874 FETCH_ARG (4, regno
);
877 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
878 "%s", reg_names
[regno
]);
879 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, "@");
883 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, "@(");
884 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
885 "%s", reg_names
[regno
]);
886 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, ")");
892 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
899 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
900 "%s", reg_names
[val
& 7]);
902 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_immediate
,
908 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
909 "%s", reg_names
[val
+ 8]);
910 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, "@+");
915 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
916 "%s", reg_names
[val
+ 8]);
917 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, "@-");
924 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, "{");
925 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
926 "%s", reg_names
[val
]);
927 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, "}");
929 else if (place
== 'C')
932 if (val
> 63) /* This is a signed constant. */
934 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, "{");
935 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_immediate
,
937 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, "}");
940 return PRINT_INSN_ARG_INVALID_OPERAND
;
945 p1
= buffer
+ (*d
== '#' ? 2 : 4);
948 else if (place
== 'C')
950 else if (place
== '8')
952 else if (place
== '3')
954 else if (place
== 'b')
956 else if (place
== 'w' || place
== 'W')
957 NEXTWORD (p1
, val
, PRINT_INSN_ARG_MEMORY_ERROR
);
958 else if (place
== 'l')
959 NEXTLONG (p1
, val
, PRINT_INSN_ARG_MEMORY_ERROR
);
961 return PRINT_INSN_ARG_INVALID_OP_TABLE
;
963 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_immediate
,
970 else if (place
== 'B')
971 disp
= COERCE_SIGNED_CHAR (buffer
[1]);
972 else if (place
== 'w' || place
== 'W')
973 NEXTWORD (p
, disp
, PRINT_INSN_ARG_MEMORY_ERROR
);
974 else if (place
== 'l' || place
== 'L' || place
== 'C')
975 NEXTLONG (p
, disp
, PRINT_INSN_ARG_MEMORY_ERROR
);
976 else if (place
== 'g')
978 NEXTBYTE (buffer
, disp
);
980 NEXTWORD (p
, disp
, PRINT_INSN_ARG_MEMORY_ERROR
);
982 NEXTLONG (p
, disp
, PRINT_INSN_ARG_MEMORY_ERROR
);
984 else if (place
== 'c')
986 if (buffer
[1] & 0x40) /* If bit six is one, long offset. */
987 NEXTLONG (p
, disp
, PRINT_INSN_ARG_MEMORY_ERROR
);
989 NEXTWORD (p
, disp
, PRINT_INSN_ARG_MEMORY_ERROR
);
992 return PRINT_INSN_ARG_INVALID_OP_TABLE
;
994 (*info
->print_address_func
) (addr
+ disp
, info
);
1001 NEXTWORD (p
, val
, PRINT_INSN_ARG_MEMORY_ERROR
);
1002 FETCH_ARG (3, val1
);
1003 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
1004 "%s", reg_names
[val1
+ 8]);
1005 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, "@(");
1006 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_address_offset
,
1008 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, ")");
1014 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
1015 "%s", fpcr_names
[val
]);
1020 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
1026 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
1027 "%%accext%s", val
== 0 ? "01" : "23");
1033 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_sub_mnemonic
,
1036 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_sub_mnemonic
,
1039 return PRINT_INSN_ARG_INVALID_OPERAND
;
1043 /* Get coprocessor ID... */
1044 val
= fetch_arg (buffer
, 'd', 3, info
);
1046 return PRINT_INSN_ARG_MEMORY_ERROR
;
1047 if (val
!= 1) /* Unusual coprocessor ID? */
1048 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
,
1078 val
= fetch_arg (buffer
, 'x', 6, info
);
1080 return PRINT_INSN_ARG_MEMORY_ERROR
;
1081 val
= ((val
& 7) << 3) + ((val
>> 3) & 7);
1085 val
= fetch_arg (buffer
, 's', 6, info
);
1087 return PRINT_INSN_ARG_MEMORY_ERROR
;
1090 /* If the <ea> is invalid for *d, then reject this match. */
1091 if (!m68k_valid_ea (*d
, val
))
1092 return PRINT_INSN_ARG_INVALID_OPERAND
;
1094 /* Get register number assuming address register. */
1095 regno
= (val
& 7) + 8;
1096 regname
= reg_names
[regno
];
1100 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
1101 "%s", reg_names
[val
]);
1105 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
1110 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
1112 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, "@");
1116 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
1118 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, "@+");
1122 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
1124 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, "@-");
1128 NEXTWORD (p
, val
, PRINT_INSN_ARG_MEMORY_ERROR
);
1129 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
1131 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, "@(");
1132 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_address_offset
,
1134 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, ")");
1138 p
= print_indexed (regno
, p
, addr
, info
);
1140 return PRINT_INSN_ARG_MEMORY_ERROR
;
1147 NEXTWORD (p
, val
, PRINT_INSN_ARG_MEMORY_ERROR
);
1148 (*info
->print_address_func
) (val
, info
);
1152 NEXTULONG (p
, uval
);
1153 (*info
->print_address_func
) (uval
, info
);
1157 NEXTWORD (p
, val
, PRINT_INSN_ARG_MEMORY_ERROR
);
1158 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
1160 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, "@(");
1161 (*info
->print_address_func
) (addr
+ val
, info
);
1162 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
, ")");
1166 p
= print_indexed (-1, p
, addr
, info
);
1168 return PRINT_INSN_ARG_MEMORY_ERROR
;
1172 flt_p
= 1; /* Assume it's a float... */
1181 NEXTWORD (p
, val
, PRINT_INSN_ARG_MEMORY_ERROR
);
1186 NEXTLONG (p
, val
, PRINT_INSN_ARG_MEMORY_ERROR
);
1191 NEXTSINGLE (flval
, p
);
1195 NEXTDOUBLE (flval
, p
);
1199 NEXTEXTEND (flval
, p
);
1203 NEXTPACKED (p
, flval
);
1207 return PRINT_INSN_ARG_INVALID_OPERAND
;
1209 if (flt_p
) /* Print a float? */
1210 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_immediate
,
1213 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_immediate
,
1218 return PRINT_INSN_ARG_INVALID_OPERAND
;
1222 /* If place is '/', then this is the case of the mask bit for
1223 mac/emac loads. Now that the arg has been printed, grab the
1224 mask bit and if set, add a '&' to the arg. */
1229 info
->fprintf_styled_func (info
->stream
, dis_style_text
, "&");
1239 NEXTWORD (p1
, val
, PRINT_INSN_ARG_MEMORY_ERROR
);
1240 /* Move the pointer ahead if this point is farther ahead
1242 p
= p1
> p
? p1
: p
;
1245 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_immediate
,
1253 for (regno
= 0; regno
< 16; ++regno
)
1254 if (val
& (0x8000 >> regno
))
1255 newval
|= 1 << regno
;
1260 for (regno
= 0; regno
< 16; ++regno
)
1261 if (val
& (1 << regno
))
1266 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
,
1269 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
1270 "%s", reg_names
[regno
]);
1271 first_regno
= regno
;
1272 while (val
& (1 << (regno
+ 1)))
1274 if (regno
> first_regno
)
1276 (*info
->fprintf_styled_func
) (info
->stream
,
1277 dis_style_text
, "-");
1278 (*info
->fprintf_styled_func
) (info
->stream
,
1279 dis_style_register
, "%s",
1284 else if (place
== '3')
1286 /* `fmovem' insn. */
1292 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_immediate
,
1300 for (regno
= 0; regno
< 8; ++regno
)
1301 if (val
& (0x80 >> regno
))
1302 newval
|= 1 << regno
;
1307 for (regno
= 0; regno
< 8; ++regno
)
1308 if (val
& (1 << regno
))
1312 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
,
1315 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
1317 first_regno
= regno
;
1318 while (val
& (1 << (regno
+ 1)))
1320 if (regno
> first_regno
)
1322 (*info
->fprintf_styled_func
) (info
->stream
,
1323 dis_style_text
, "-");
1324 (*info
->fprintf_styled_func
) (info
->stream
,
1330 else if (place
== '8')
1333 /* fmoveml for FP status registers. */
1334 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
1335 "%s", fpcr_names
[val
]);
1338 return PRINT_INSN_ARG_INVALID_OP_TABLE
;
1357 case 2: name
= "%tt0"; break;
1358 case 3: name
= "%tt1"; break;
1359 case 0x10: name
= "%tc"; break;
1360 case 0x11: name
= "%drp"; break;
1361 case 0x12: name
= "%srp"; break;
1362 case 0x13: name
= "%crp"; break;
1363 case 0x14: name
= "%cal"; break;
1364 case 0x15: name
= "%val"; break;
1365 case 0x16: name
= "%scc"; break;
1366 case 0x17: name
= "%ac"; break;
1367 case 0x18: name
= "%psr"; break;
1368 case 0x19: name
= "%pcsr"; break;
1372 int break_reg
= ((buffer
[3] >> 2) & 7);
1374 (*info
->fprintf_styled_func
)
1375 (info
->stream
, dis_style_register
,
1376 val
== 0x1c ? "%%bad%d" : "%%bac%d", break_reg
);
1380 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
,
1381 "<mmu register %d>", val
);
1384 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
1395 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
1398 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
,
1401 /* xgettext:c-format */
1402 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_text
,
1403 _("<function code %d>"), fc
);
1408 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
, "%%val");
1415 FETCH_ARG (3, level
);
1416 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_immediate
,
1432 (*info
->fprintf_styled_func
) (info
->stream
, dis_style_register
, "%s%s",
1433 reg_half_names
[reg
],
1434 is_upper
? "u" : "l");
1439 return PRINT_INSN_ARG_INVALID_OP_TABLE
;
1445 /* Try to match the current instruction to best and if so, return the
1446 number of bytes consumed from the instruction stream, else zero.
1447 Return -1 on memory error. */
1450 match_insn_m68k (bfd_vma memaddr
,
1451 disassemble_info
* info
,
1452 const struct m68k_opcode
* best
)
1454 unsigned char *save_p
;
1457 const char *args
= best
->args
;
1459 struct private *priv
= (struct private *) info
->private_data
;
1460 bfd_byte
*buffer
= priv
->the_buffer
;
1461 fprintf_styled_ftype save_printer
= info
->fprintf_styled_func
;
1462 void (* save_print_address
) (bfd_vma
, struct disassemble_info
*)
1463 = info
->print_address_func
;
1468 /* Point at first word of argument data,
1469 and at descriptor for first argument. */
1472 /* Figure out how long the fixed-size portion of the instruction is.
1473 The only place this is stored in the opcode table is
1474 in the arguments--look for arguments which specify fields in the 2nd
1475 or 3rd words of the instruction. */
1476 for (d
= args
; *d
; d
+= 2)
1478 /* I don't think it is necessary to be checking d[0] here;
1479 I suspect all this could be moved to the case statement below. */
1482 if (d
[1] == 'l' && p
- buffer
< 6)
1484 else if (p
- buffer
< 4 && d
[1] != 'C' && d
[1] != '8')
1488 if ((d
[0] == 'L' || d
[0] == 'l') && d
[1] == 'w' && p
- buffer
< 4)
1514 /* pflusha is an exceptions. It takes no arguments but is two words
1515 long. Recognize it by looking at the lower 16 bits of the mask. */
1516 if (p
- buffer
< 4 && (best
->match
& 0xFFFF) != 0)
1519 /* lpstop is another exception. It takes a one word argument but is
1520 three words long. */
1522 && (best
->match
& 0xffff) == 0xffff
1526 /* Copy the one word argument into the usual location for a one
1527 word argument, to simplify printing it. We can get away with
1528 this because we know exactly what the second word is, and we
1529 aren't going to print anything based on it. */
1531 if (!FETCH_DATA (info
, p
))
1533 buffer
[2] = buffer
[4];
1534 buffer
[3] = buffer
[5];
1537 if (!FETCH_DATA (info
, p
))
1541 info
->print_address_func
= dummy_print_address
;
1542 info
->fprintf_styled_func
= dummy_printer
;
1544 /* We scan the operands twice. The first time we don't print anything,
1545 but look for errors. */
1546 for (d
= args
; *d
; d
+= 2)
1548 int eaten
= print_insn_arg (d
, buffer
, p
, memaddr
+ (p
- buffer
), info
);
1552 else if (eaten
== PRINT_INSN_ARG_INVALID_OPERAND
1553 || eaten
== PRINT_INSN_ARG_MEMORY_ERROR
)
1555 info
->fprintf_styled_func
= save_printer
;
1556 info
->print_address_func
= save_print_address
;
1557 return eaten
== PRINT_INSN_ARG_MEMORY_ERROR
? -1 : 0;
1561 /* We must restore the print functions before trying to print the
1563 info
->fprintf_styled_func
= save_printer
;
1564 info
->print_address_func
= save_print_address
;
1565 info
->fprintf_styled_func (info
->stream
, dis_style_text
,
1566 /* xgettext:c-format */
1567 _("<internal error in opcode table: %s %s>\n"),
1568 best
->name
, best
->args
);
1574 info
->fprintf_styled_func
= save_printer
;
1575 info
->print_address_func
= save_print_address
;
1579 info
->fprintf_styled_func (info
->stream
, dis_style_mnemonic
, "%s", best
->name
);
1582 info
->fprintf_styled_func (info
->stream
, dis_style_text
, " ");
1586 p
+= print_insn_arg (d
, buffer
, p
, memaddr
+ (p
- buffer
), info
);
1589 if (*d
&& *(d
- 2) != 'I' && *d
!= 'k')
1590 info
->fprintf_styled_func (info
->stream
, dis_style_text
, ",");
1596 /* Try to interpret the instruction at address MEMADDR as one that
1597 can execute on a processor with the features given by ARCH_MASK.
1598 If successful, print the instruction to INFO->STREAM and return
1599 its length in bytes. Return 0 otherwise. Return -1 on memory
1603 m68k_scan_mask (bfd_vma memaddr
, disassemble_info
*info
,
1604 unsigned int arch_mask
)
1608 static const struct m68k_opcode
**opcodes
[16];
1609 static int numopcodes
[16];
1613 struct private *priv
= (struct private *) info
->private_data
;
1614 bfd_byte
*buffer
= priv
->the_buffer
;
1618 /* Speed up the matching by sorting the opcode
1619 table on the upper four bits of the opcode. */
1620 const struct m68k_opcode
**opc_pointer
[16];
1622 /* First count how many opcodes are in each of the sixteen buckets. */
1623 for (i
= 0; i
< m68k_numopcodes
; i
++)
1624 numopcodes
[(m68k_opcodes
[i
].opcode
>> 28) & 15]++;
1626 /* Then create a sorted table of pointers
1627 that point into the unsorted table. */
1628 opc_pointer
[0] = xmalloc (sizeof (struct m68k_opcode
*)
1630 opcodes
[0] = opc_pointer
[0];
1632 for (i
= 1; i
< 16; i
++)
1634 opc_pointer
[i
] = opc_pointer
[i
- 1] + numopcodes
[i
- 1];
1635 opcodes
[i
] = opc_pointer
[i
];
1638 for (i
= 0; i
< m68k_numopcodes
; i
++)
1639 *opc_pointer
[(m68k_opcodes
[i
].opcode
>> 28) & 15]++ = &m68k_opcodes
[i
];
1642 if (!FETCH_DATA (info
, buffer
+ 2))
1644 major_opcode
= (buffer
[0] >> 4) & 15;
1646 for (i
= 0; i
< numopcodes
[major_opcode
]; i
++)
1648 const struct m68k_opcode
*opc
= opcodes
[major_opcode
][i
];
1649 unsigned long opcode
= opc
->opcode
;
1650 unsigned long match
= opc
->match
;
1651 const char *args
= opc
->args
;
1656 if (((0xff & buffer
[0] & (match
>> 24)) == (0xff & (opcode
>> 24)))
1657 && ((0xff & buffer
[1] & (match
>> 16)) == (0xff & (opcode
>> 16)))
1658 /* Only fetch the next two bytes if we need to. */
1659 && (((0xffff & match
) == 0)
1661 (FETCH_DATA (info
, buffer
+ 4)
1662 && ((0xff & buffer
[2] & (match
>> 8)) == (0xff & (opcode
>> 8)))
1663 && ((0xff & buffer
[3] & match
) == (0xff & opcode
)))
1665 && (opc
->arch
& arch_mask
) != 0)
1667 /* Don't use for printout the variants of divul and divsl
1668 that have the same register number in two places.
1669 The more general variants will match instead. */
1670 for (d
= args
; *d
; d
+= 2)
1674 /* Don't use for printout the variants of most floating
1675 point coprocessor instructions which use the same
1676 register number in two places, as above. */
1678 for (d
= args
; *d
; d
+= 2)
1682 /* Don't match fmovel with more than one register;
1683 wait for fmoveml. */
1686 for (d
= args
; *d
; d
+= 2)
1688 if (d
[0] == 's' && d
[1] == '8')
1690 val
= fetch_arg (buffer
, d
[1], 3, info
);
1693 if ((val
& (val
- 1)) != 0)
1699 /* Don't match FPU insns with non-default coprocessor ID. */
1702 for (d
= args
; *d
; d
+= 2)
1706 val
= fetch_arg (buffer
, 'd', 3, info
);
1714 if ((val
= match_insn_m68k (memaddr
, info
, opc
)))
1721 /* Print the m68k instruction at address MEMADDR in debugged memory,
1722 on INFO->STREAM. Returns length of the instruction, in bytes. */
1725 print_insn_m68k (bfd_vma memaddr
, disassemble_info
*info
)
1727 unsigned int arch_mask
;
1728 struct private priv
;
1731 bfd_byte
*buffer
= priv
.the_buffer
;
1733 info
->private_data
= & priv
;
1734 /* Tell objdump to use two bytes per chunk
1735 and six bytes per line for displaying raw data. */
1736 info
->bytes_per_chunk
= 2;
1737 info
->bytes_per_line
= 6;
1738 info
->display_endian
= BFD_ENDIAN_BIG
;
1739 priv
.max_fetched
= priv
.the_buffer
;
1740 priv
.insn_start
= memaddr
;
1742 arch_mask
= bfd_m68k_mach_to_features (info
->mach
);
1745 /* First try printing an m680x0 instruction. Try printing a Coldfire
1746 one if that fails. */
1747 val
= m68k_scan_mask (memaddr
, info
, m68k_mask
);
1749 val
= m68k_scan_mask (memaddr
, info
, mcf_mask
);
1753 val
= m68k_scan_mask (memaddr
, info
, arch_mask
);
1758 /* Handle undefined instructions. */
1759 info
->fprintf_styled_func (info
->stream
, dis_style_assembler_directive
,
1761 info
->fprintf_styled_func (info
->stream
, dis_style_text
, " ");
1762 info
->fprintf_styled_func (info
->stream
, dis_style_immediate
,
1763 "0x%04x", (buffer
[0] << 8) + buffer
[1]);
1766 return val
? val
: 2;