1 /* Disassemble MN10300 instructions.
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 #include "opcode/mn10300.h"
26 static void disassemble
PARAMS ((bfd_vma
, struct disassemble_info
*,
27 unsigned long insn
, unsigned int));
29 #define HAVE_AM33_2 (info->mach == AM33_2)
30 #define HAVE_AM33 (info->mach == AM33 || HAVE_AM33_2)
31 #define HAVE_AM30 (info->mach == AM30)
34 print_insn_mn10300 (memaddr
, info
)
36 struct disassemble_info
*info
;
43 /* First figure out how big the opcode is. */
44 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 1, info
);
47 (*info
->memory_error_func
) (status
, memaddr
, info
);
50 insn
= *(unsigned char *) buffer
;
52 /* These are one byte insns. */
53 if ((insn
& 0xf3) == 0x00
54 || (insn
& 0xf0) == 0x10
55 || (insn
& 0xfc) == 0x3c
56 || (insn
& 0xf3) == 0x41
57 || (insn
& 0xf3) == 0x40
58 || (insn
& 0xfc) == 0x50
59 || (insn
& 0xfc) == 0x54
60 || (insn
& 0xf0) == 0x60
61 || (insn
& 0xf0) == 0x70
62 || ((insn
& 0xf0) == 0x80
63 && (insn
& 0x0c) >> 2 != (insn
& 0x03))
64 || ((insn
& 0xf0) == 0x90
65 && (insn
& 0x0c) >> 2 != (insn
& 0x03))
66 || ((insn
& 0xf0) == 0xa0
67 && (insn
& 0x0c) >> 2 != (insn
& 0x03))
68 || ((insn
& 0xf0) == 0xb0
69 && (insn
& 0x0c) >> 2 != (insn
& 0x03))
70 || (insn
& 0xff) == 0xcb
71 || (insn
& 0xfc) == 0xd0
72 || (insn
& 0xfc) == 0xd4
73 || (insn
& 0xfc) == 0xd8
74 || (insn
& 0xf0) == 0xe0
75 || (insn
& 0xff) == 0xff)
80 /* These are two byte insns. */
81 else if ((insn
& 0xf0) == 0x80
82 || (insn
& 0xf0) == 0x90
83 || (insn
& 0xf0) == 0xa0
84 || (insn
& 0xf0) == 0xb0
85 || (insn
& 0xfc) == 0x20
86 || (insn
& 0xfc) == 0x28
87 || (insn
& 0xf3) == 0x43
88 || (insn
& 0xf3) == 0x42
89 || (insn
& 0xfc) == 0x58
90 || (insn
& 0xfc) == 0x5c
91 || ((insn
& 0xf0) == 0xc0
92 && (insn
& 0xff) != 0xcb
93 && (insn
& 0xff) != 0xcc
94 && (insn
& 0xff) != 0xcd)
95 || (insn
& 0xff) == 0xf0
96 || (insn
& 0xff) == 0xf1
97 || (insn
& 0xff) == 0xf2
98 || (insn
& 0xff) == 0xf3
99 || (insn
& 0xff) == 0xf4
100 || (insn
& 0xff) == 0xf5
101 || (insn
& 0xff) == 0xf6)
103 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
106 (*info
->memory_error_func
) (status
, memaddr
, info
);
109 insn
= bfd_getb16 (buffer
);
113 /* These are three byte insns. */
114 else if ((insn
& 0xff) == 0xf8
115 || (insn
& 0xff) == 0xcc
116 || (insn
& 0xff) == 0xf9
117 || (insn
& 0xf3) == 0x01
118 || (insn
& 0xf3) == 0x02
119 || (insn
& 0xf3) == 0x03
120 || (insn
& 0xfc) == 0x24
121 || (insn
& 0xfc) == 0x2c
122 || (insn
& 0xfc) == 0x30
123 || (insn
& 0xfc) == 0x34
124 || (insn
& 0xfc) == 0x38
125 || (insn
& 0xff) == 0xde
126 || (insn
& 0xff) == 0xdf
127 || (insn
& 0xff) == 0xf9
128 || (insn
& 0xff) == 0xcc)
130 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
133 (*info
->memory_error_func
) (status
, memaddr
, info
);
136 insn
= bfd_getb16 (buffer
);
138 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 1, info
);
141 (*info
->memory_error_func
) (status
, memaddr
, info
);
144 insn
|= *(unsigned char *) buffer
;
148 /* These are four byte insns. */
149 else if ((insn
& 0xff) == 0xfa
150 || (insn
& 0xff) == 0xf7
151 || (insn
& 0xff) == 0xfb)
153 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
156 (*info
->memory_error_func
) (status
, memaddr
, info
);
159 insn
= bfd_getb32 (buffer
);
163 /* These are five byte insns. */
164 else if ((insn
& 0xff) == 0xcd
165 || (insn
& 0xff) == 0xdc)
167 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
170 (*info
->memory_error_func
) (status
, memaddr
, info
);
173 insn
= bfd_getb32 (buffer
);
177 /* These are six byte insns. */
178 else if ((insn
& 0xff) == 0xfd
179 || (insn
& 0xff) == 0xfc)
181 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
184 (*info
->memory_error_func
) (status
, memaddr
, info
);
188 insn
= bfd_getb32 (buffer
);
192 /* Else its a seven byte insns (in theory). */
195 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
198 (*info
->memory_error_func
) (status
, memaddr
, info
);
202 insn
= bfd_getb32 (buffer
);
204 /* Handle the 5-byte extended instruction codes. */
205 if ((insn
& 0xfff80000) == 0xfe800000)
209 disassemble (memaddr
, info
, insn
, consume
);
215 disassemble (memaddr
, info
, insn
, size
)
217 struct disassemble_info
*info
;
221 struct mn10300_opcode
*op
= (struct mn10300_opcode
*)mn10300_opcodes
;
222 const struct mn10300_operand
*operand
;
224 unsigned long extension
= 0;
225 int status
, match
= 0;
227 /* Find the opcode. */
230 int mysize
, extra_shift
;
232 if (op
->format
== FMT_S0
)
234 else if (op
->format
== FMT_S1
235 || op
->format
== FMT_D0
)
237 else if (op
->format
== FMT_S2
238 || op
->format
== FMT_D1
)
240 else if (op
->format
== FMT_S4
)
242 else if (op
->format
== FMT_D2
)
244 else if (op
->format
== FMT_D3
)
246 else if (op
->format
== FMT_D4
)
248 else if (op
->format
== FMT_D6
)
250 else if (op
->format
== FMT_D7
|| op
->format
== FMT_D10
)
252 else if (op
->format
== FMT_D8
)
254 else if (op
->format
== FMT_D9
)
259 if ((op
->mask
& insn
) == op
->opcode
260 && size
== (unsigned int) mysize
262 || (op
->machine
== AM33_2
&& HAVE_AM33_2
)
263 || (op
->machine
== AM33
&& HAVE_AM33
)
264 || (op
->machine
== AM30
&& HAVE_AM30
)))
266 const unsigned char *opindex_ptr
;
267 unsigned int nocomma
;
270 if (op
->format
== FMT_D1
|| op
->format
== FMT_S1
)
272 else if (op
->format
== FMT_D2
|| op
->format
== FMT_D4
273 || op
->format
== FMT_S2
|| op
->format
== FMT_S4
274 || op
->format
== FMT_S6
|| op
->format
== FMT_D5
)
276 else if (op
->format
== FMT_D7
277 || op
->format
== FMT_D8
278 || op
->format
== FMT_D9
)
283 if (size
== 1 || size
== 2)
288 && (op
->format
== FMT_D1
289 || op
->opcode
== 0xdf0000
290 || op
->opcode
== 0xde0000))
295 && op
->format
== FMT_D6
)
302 status
= (*info
->read_memory_func
) (memaddr
+ 1, buffer
, 2, info
);
305 (*info
->memory_error_func
) (status
, memaddr
, info
);
309 insn
|= bfd_getl16 (buffer
);
313 && (op
->opcode
== 0xfaf80000
314 || op
->opcode
== 0xfaf00000
315 || op
->opcode
== 0xfaf40000))
320 && (op
->format
== FMT_D7
321 || op
->format
== FMT_D10
))
328 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
331 (*info
->memory_error_func
) (status
, memaddr
, info
);
335 insn
|= bfd_getl16 (buffer
);
338 else if (size
== 5 && op
->opcode
== 0xdc000000)
340 unsigned long temp
= 0;
341 status
= (*info
->read_memory_func
) (memaddr
+ 1, buffer
, 4, info
);
344 (*info
->memory_error_func
) (status
, memaddr
, info
);
347 temp
|= bfd_getl32 (buffer
);
350 insn
|= (temp
& 0xffffff00) >> 8;
351 extension
= temp
& 0xff;
353 else if (size
== 5 && op
->format
== FMT_D3
)
355 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
358 (*info
->memory_error_func
) (status
, memaddr
, info
);
362 insn
|= bfd_getl16 (buffer
);
364 status
= (*info
->read_memory_func
) (memaddr
+ 4, buffer
, 1, info
);
367 (*info
->memory_error_func
) (status
, memaddr
, info
);
370 extension
= *(unsigned char *) buffer
;
374 unsigned long temp
= 0;
375 status
= (*info
->read_memory_func
) (memaddr
+ 1, buffer
, 2, info
);
378 (*info
->memory_error_func
) (status
, memaddr
, info
);
381 temp
|= bfd_getl16 (buffer
);
386 status
= (*info
->read_memory_func
) (memaddr
+ 4, buffer
, 1, info
);
389 (*info
->memory_error_func
) (status
, memaddr
, info
);
392 extension
= *(unsigned char *) buffer
;
394 else if (size
== 6 && op
->format
== FMT_D8
)
397 status
= (*info
->read_memory_func
) (memaddr
+ 5, buffer
, 1, info
);
400 (*info
->memory_error_func
) (status
, memaddr
, info
);
403 insn
|= *(unsigned char *) buffer
;
405 status
= (*info
->read_memory_func
) (memaddr
+ 3, buffer
, 2, info
);
408 (*info
->memory_error_func
) (status
, memaddr
, info
);
411 extension
= bfd_getl16 (buffer
);
415 unsigned long temp
= 0;
416 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 4, info
);
419 (*info
->memory_error_func
) (status
, memaddr
, info
);
422 temp
|= bfd_getl32 (buffer
);
425 insn
|= (temp
>> 16) & 0xffff;
426 extension
= temp
& 0xffff;
428 else if (size
== 7 && op
->format
== FMT_D9
)
431 status
= (*info
->read_memory_func
) (memaddr
+ 3, buffer
, 4, info
);
434 (*info
->memory_error_func
) (status
, memaddr
, info
);
437 extension
= bfd_getl32 (buffer
);
438 insn
|= (extension
& 0xff000000) >> 24;
439 extension
&= 0xffffff;
441 else if (size
== 7 && op
->opcode
== 0xdd000000)
443 unsigned long temp
= 0;
444 status
= (*info
->read_memory_func
) (memaddr
+ 1, buffer
, 4, info
);
447 (*info
->memory_error_func
) (status
, memaddr
, info
);
450 temp
|= bfd_getl32 (buffer
);
453 insn
|= (temp
>> 8) & 0xffffff;
454 extension
= (temp
& 0xff) << 16;
456 status
= (*info
->read_memory_func
) (memaddr
+ 5, buffer
, 2, info
);
459 (*info
->memory_error_func
) (status
, memaddr
, info
);
462 extension
|= bfd_getb16 (buffer
);
466 unsigned long temp
= 0;
467 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 4, info
);
470 (*info
->memory_error_func
) (status
, memaddr
, info
);
473 temp
|= bfd_getl32 (buffer
);
476 insn
|= (temp
>> 16) & 0xffff;
477 extension
= (temp
& 0xffff) << 8;
479 status
= (*info
->read_memory_func
) (memaddr
+ 6, buffer
, 1, info
);
482 (*info
->memory_error_func
) (status
, memaddr
, info
);
485 extension
|= *(unsigned char *) buffer
;
489 (*info
->fprintf_func
) (info
->stream
, "%s\t", op
->name
);
491 /* Now print the operands. */
492 for (opindex_ptr
= op
->operands
, nocomma
= 1;
498 operand
= &mn10300_operands
[*opindex_ptr
];
500 /* If this operand is a PLUS (autoincrement), then do not emit
501 a comma before emitting the plus. */
502 if ((operand
->flags
& MN10300_OPERAND_PLUS
) != 0)
505 if ((operand
->flags
& MN10300_OPERAND_SPLIT
) != 0)
508 value
= insn
& ((1 << operand
->bits
) - 1);
509 value
<<= (32 - operand
->bits
);
510 temp
= extension
>> operand
->shift
;
511 temp
&= ((1 << (32 - operand
->bits
)) - 1);
513 value
= ((value
^ (((unsigned long) 1) << 31))
514 - (((unsigned long) 1) << 31));
516 else if ((operand
->flags
& MN10300_OPERAND_24BIT
) != 0)
519 value
= insn
& ((1 << operand
->bits
) - 1);
520 value
<<= (24 - operand
->bits
);
521 temp
= extension
>> operand
->shift
;
522 temp
&= ((1 << (24 - operand
->bits
)) - 1);
524 if ((operand
->flags
& MN10300_OPERAND_SIGNED
) != 0)
525 value
= ((value
& 0xffffff) ^ 0x800000) - 0x800000;
527 else if ((operand
->flags
& (MN10300_OPERAND_FSREG
528 | MN10300_OPERAND_FDREG
)))
530 /* See m10300-opc.c just before #define FSM0 for an
531 explanation of these variables. Note that
532 FMT-implied shifts are not taken into account for
534 unsigned long mask_low
, mask_high
;
535 int shl_low
, shr_high
, shl_high
;
537 switch (operand
->bits
)
540 /* Handle regular FP registers. */
541 if (operand
->shift
>= 0)
543 /* This is an `m' register. */
544 shl_low
= operand
->shift
;
545 shl_high
= 8 + (8 & shl_low
) + (shl_low
& 4) / 4;
549 /* This is an `n' register. */
550 shl_low
= -operand
->shift
;
551 shl_high
= shl_low
/ 4;
559 /* Handle accumulators. */
560 shl_low
= -operand
->shift
;
570 value
= ((((insn
>> shl_high
) << shr_high
) & mask_high
)
571 | ((insn
>> shl_low
) & mask_low
));
573 else if ((operand
->flags
& MN10300_OPERAND_EXTENDED
) != 0)
575 value
= ((extension
>> (operand
->shift
))
576 & ((1 << operand
->bits
) - 1));
580 value
= ((insn
>> (operand
->shift
))
581 & ((1 << operand
->bits
) - 1));
584 if ((operand
->flags
& MN10300_OPERAND_SIGNED
) != 0
585 /* These are properly extended by the code above. */
586 && ((operand
->flags
& MN10300_OPERAND_24BIT
) == 0))
587 value
= ((value
^ (((unsigned long) 1) << (operand
->bits
- 1)))
588 - (((unsigned long) 1) << (operand
->bits
- 1)));
592 || ((operand
->flags
& MN10300_OPERAND_PAREN
) == 0)))
593 (*info
->fprintf_func
) (info
->stream
, ",");
597 if ((operand
->flags
& MN10300_OPERAND_DREG
) != 0)
599 value
= ((insn
>> (operand
->shift
+ extra_shift
))
600 & ((1 << operand
->bits
) - 1));
601 (*info
->fprintf_func
) (info
->stream
, "d%d", (int) value
);
604 else if ((operand
->flags
& MN10300_OPERAND_AREG
) != 0)
606 value
= ((insn
>> (operand
->shift
+ extra_shift
))
607 & ((1 << operand
->bits
) - 1));
608 (*info
->fprintf_func
) (info
->stream
, "a%d", (int) value
);
611 else if ((operand
->flags
& MN10300_OPERAND_SP
) != 0)
612 (*info
->fprintf_func
) (info
->stream
, "sp");
614 else if ((operand
->flags
& MN10300_OPERAND_PSW
) != 0)
615 (*info
->fprintf_func
) (info
->stream
, "psw");
617 else if ((operand
->flags
& MN10300_OPERAND_MDR
) != 0)
618 (*info
->fprintf_func
) (info
->stream
, "mdr");
620 else if ((operand
->flags
& MN10300_OPERAND_RREG
) != 0)
622 value
= ((insn
>> (operand
->shift
+ extra_shift
))
623 & ((1 << operand
->bits
) - 1));
625 (*info
->fprintf_func
) (info
->stream
, "r%d", (int) value
);
627 (*info
->fprintf_func
) (info
->stream
, "a%d", (int) value
- 8);
629 (*info
->fprintf_func
) (info
->stream
, "d%d", (int) value
- 12);
632 else if ((operand
->flags
& MN10300_OPERAND_XRREG
) != 0)
634 value
= ((insn
>> (operand
->shift
+ extra_shift
))
635 & ((1 << operand
->bits
) - 1));
637 (*info
->fprintf_func
) (info
->stream
, "sp", value
);
639 (*info
->fprintf_func
) (info
->stream
, "xr%d", (int) value
);
642 else if ((operand
->flags
& MN10300_OPERAND_FSREG
) != 0)
643 (*info
->fprintf_func
) (info
->stream
, "fs%d", (int) value
);
645 else if ((operand
->flags
& MN10300_OPERAND_FDREG
) != 0)
646 (*info
->fprintf_func
) (info
->stream
, "fd%d", (int) value
);
648 else if ((operand
->flags
& MN10300_OPERAND_FPCR
) != 0)
649 (*info
->fprintf_func
) (info
->stream
, "fpcr");
651 else if ((operand
->flags
& MN10300_OPERAND_USP
) != 0)
652 (*info
->fprintf_func
) (info
->stream
, "usp");
654 else if ((operand
->flags
& MN10300_OPERAND_SSP
) != 0)
655 (*info
->fprintf_func
) (info
->stream
, "ssp");
657 else if ((operand
->flags
& MN10300_OPERAND_MSP
) != 0)
658 (*info
->fprintf_func
) (info
->stream
, "msp");
660 else if ((operand
->flags
& MN10300_OPERAND_PC
) != 0)
661 (*info
->fprintf_func
) (info
->stream
, "pc");
663 else if ((operand
->flags
& MN10300_OPERAND_EPSW
) != 0)
664 (*info
->fprintf_func
) (info
->stream
, "epsw");
666 else if ((operand
->flags
& MN10300_OPERAND_PLUS
) != 0)
667 (*info
->fprintf_func
) (info
->stream
, "+");
669 else if ((operand
->flags
& MN10300_OPERAND_PAREN
) != 0)
672 (*info
->fprintf_func
) (info
->stream
, ")");
675 (*info
->fprintf_func
) (info
->stream
, "(");
681 else if ((operand
->flags
& MN10300_OPERAND_PCREL
) != 0)
682 (*info
->print_address_func
) ((long) value
+ memaddr
, info
);
684 else if ((operand
->flags
& MN10300_OPERAND_MEMADDR
) != 0)
685 (*info
->print_address_func
) (value
, info
);
687 else if ((operand
->flags
& MN10300_OPERAND_REG_LIST
) != 0)
691 (*info
->fprintf_func
) (info
->stream
, "[");
694 (*info
->fprintf_func
) (info
->stream
, "d2");
701 (*info
->fprintf_func
) (info
->stream
, ",");
702 (*info
->fprintf_func
) (info
->stream
, "d3");
709 (*info
->fprintf_func
) (info
->stream
, ",");
710 (*info
->fprintf_func
) (info
->stream
, "a2");
717 (*info
->fprintf_func
) (info
->stream
, ",");
718 (*info
->fprintf_func
) (info
->stream
, "a3");
725 (*info
->fprintf_func
) (info
->stream
, ",");
726 (*info
->fprintf_func
) (info
->stream
, "other");
733 (*info
->fprintf_func
) (info
->stream
, ",");
734 (*info
->fprintf_func
) (info
->stream
, "exreg0");
740 (*info
->fprintf_func
) (info
->stream
, ",");
741 (*info
->fprintf_func
) (info
->stream
, "exreg1");
747 (*info
->fprintf_func
) (info
->stream
, ",");
748 (*info
->fprintf_func
) (info
->stream
, "exother");
751 (*info
->fprintf_func
) (info
->stream
, "]");
755 (*info
->fprintf_func
) (info
->stream
, "%ld", (long) value
);
765 /* xgettext:c-format */
766 (*info
->fprintf_func
) (info
->stream
, _("unknown\t0x%04x"), insn
);