1 /* Disassemble MN10300 instructions.
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2005, 2007
3 Free Software Foundation, Inc.
5 This file is part of the GNU opcodes library.
7 This library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 It is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
25 #include "opcode/mn10300.h"
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 disassemble (bfd_vma memaddr,
35 struct disassemble_info *info,
39 struct mn10300_opcode *op = (struct mn10300_opcode *) mn10300_opcodes;
40 const struct mn10300_operand *operand;
42 unsigned long extension = 0;
43 int status, match = 0;
45 /* Find the opcode. */
48 int mysize, extra_shift;
50 if (op->format == FMT_S0)
52 else if (op->format == FMT_S1
53 || op->format == FMT_D0)
55 else if (op->format == FMT_S2
56 || op->format == FMT_D1)
58 else if (op->format == FMT_S4)
60 else if (op->format == FMT_D2)
62 else if (op->format == FMT_D3)
64 else if (op->format == FMT_D4)
66 else if (op->format == FMT_D6)
68 else if (op->format == FMT_D7 || op->format == FMT_D10)
70 else if (op->format == FMT_D8)
72 else if (op->format == FMT_D9)
77 if ((op->mask & insn) == op->opcode
78 && size == (unsigned int) mysize
80 || (op->machine == AM33_2 && HAVE_AM33_2)
81 || (op->machine == AM33 && HAVE_AM33)
82 || (op->machine == AM30 && HAVE_AM30)))
84 const unsigned char *opindex_ptr;
88 if (op->format == FMT_D1 || op->format == FMT_S1)
90 else if (op->format == FMT_D2 || op->format == FMT_D4
91 || op->format == FMT_S2 || op->format == FMT_S4
92 || op->format == FMT_S6 || op->format == FMT_D5)
94 else if (op->format == FMT_D7
95 || op->format == FMT_D8
96 || op->format == FMT_D9)
101 if (size == 1 || size == 2)
105 && (op->format == FMT_D1
106 || op->opcode == 0xdf0000
107 || op->opcode == 0xde0000))
111 && op->format == FMT_D6)
117 status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
120 (*info->memory_error_func) (status, memaddr, info);
124 insn |= bfd_getl16 (buffer);
128 && (op->opcode == 0xfaf80000
129 || op->opcode == 0xfaf00000
130 || op->opcode == 0xfaf40000))
134 && (op->format == FMT_D7
135 || op->format == FMT_D10))
141 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
144 (*info->memory_error_func) (status, memaddr, info);
148 insn |= bfd_getl16 (buffer);
151 else if (size == 5 && op->opcode == 0xdc000000)
153 unsigned long temp = 0;
155 status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
158 (*info->memory_error_func) (status, memaddr, info);
161 temp |= bfd_getl32 (buffer);
164 insn |= (temp & 0xffffff00) >> 8;
165 extension = temp & 0xff;
167 else if (size == 5 && op->format == FMT_D3)
169 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
172 (*info->memory_error_func) (status, memaddr, info);
176 insn |= bfd_getl16 (buffer);
178 status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
181 (*info->memory_error_func) (status, memaddr, info);
184 extension = *(unsigned char *) buffer;
188 unsigned long temp = 0;
190 status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
193 (*info->memory_error_func) (status, memaddr, info);
196 temp |= bfd_getl16 (buffer);
201 status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
204 (*info->memory_error_func) (status, memaddr, info);
207 extension = *(unsigned char *) buffer;
209 else if (size == 6 && op->format == FMT_D8)
212 status = (*info->read_memory_func) (memaddr + 5, buffer, 1, info);
215 (*info->memory_error_func) (status, memaddr, info);
218 insn |= *(unsigned char *) buffer;
220 status = (*info->read_memory_func) (memaddr + 3, buffer, 2, info);
223 (*info->memory_error_func) (status, memaddr, info);
226 extension = bfd_getl16 (buffer);
230 unsigned long temp = 0;
232 status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
235 (*info->memory_error_func) (status, memaddr, info);
238 temp |= bfd_getl32 (buffer);
241 insn |= (temp >> 16) & 0xffff;
242 extension = temp & 0xffff;
244 else if (size == 7 && op->format == FMT_D9)
247 status = (*info->read_memory_func) (memaddr + 3, buffer, 4, info);
250 (*info->memory_error_func) (status, memaddr, info);
253 extension = bfd_getl32 (buffer);
254 insn |= (extension & 0xff000000) >> 24;
255 extension &= 0xffffff;
257 else if (size == 7 && op->opcode == 0xdd000000)
259 unsigned long temp = 0;
261 status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
264 (*info->memory_error_func) (status, memaddr, info);
267 temp |= bfd_getl32 (buffer);
270 insn |= (temp >> 8) & 0xffffff;
271 extension = (temp & 0xff) << 16;
273 status = (*info->read_memory_func) (memaddr + 5, buffer, 2, info);
276 (*info->memory_error_func) (status, memaddr, info);
279 extension |= bfd_getb16 (buffer);
283 unsigned long temp = 0;
285 status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
288 (*info->memory_error_func) (status, memaddr, info);
291 temp |= bfd_getl32 (buffer);
294 insn |= (temp >> 16) & 0xffff;
295 extension = (temp & 0xffff) << 8;
297 status = (*info->read_memory_func) (memaddr + 6, buffer, 1, info);
300 (*info->memory_error_func) (status, memaddr, info);
303 extension |= *(unsigned char *) buffer;
307 (*info->fprintf_func) (info->stream, "%s\t", op->name);
309 /* Now print the operands. */
310 for (opindex_ptr = op->operands, nocomma = 1;
316 operand = &mn10300_operands[*opindex_ptr];
318 /* If this operand is a PLUS (autoincrement), then do not emit
319 a comma before emitting the plus. */
320 if ((operand->flags & MN10300_OPERAND_PLUS) != 0)
323 if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
327 value = insn & ((1 << operand->bits) - 1);
328 value <<= (32 - operand->bits);
329 temp = extension >> operand->shift;
330 temp &= ((1 << (32 - operand->bits)) - 1);
332 value = ((value ^ (((unsigned long) 1) << 31))
333 - (((unsigned long) 1) << 31));
335 else if ((operand->flags & MN10300_OPERAND_24BIT) != 0)
339 value = insn & ((1 << operand->bits) - 1);
340 value <<= (24 - operand->bits);
341 temp = extension >> operand->shift;
342 temp &= ((1 << (24 - operand->bits)) - 1);
344 if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
345 value = ((value & 0xffffff) ^ 0x800000) - 0x800000;
347 else if ((operand->flags & (MN10300_OPERAND_FSREG
348 | MN10300_OPERAND_FDREG)))
350 /* See m10300-opc.c just before #define FSM0 for an
351 explanation of these variables. Note that
352 FMT-implied shifts are not taken into account for
354 unsigned long mask_low, mask_high;
355 int shl_low, shr_high, shl_high;
357 switch (operand->bits)
360 /* Handle regular FP registers. */
361 if (operand->shift >= 0)
363 /* This is an `m' register. */
364 shl_low = operand->shift;
365 shl_high = 8 + (8 & shl_low) + (shl_low & 4) / 4;
369 /* This is an `n' register. */
370 shl_low = -operand->shift;
371 shl_high = shl_low / 4;
379 /* Handle accumulators. */
380 shl_low = -operand->shift;
390 value = ((((insn >> shl_high) << shr_high) & mask_high)
391 | ((insn >> shl_low) & mask_low));
393 else if ((operand->flags & MN10300_OPERAND_EXTENDED) != 0)
394 value = ((extension >> (operand->shift))
395 & ((1 << operand->bits) - 1));
398 value = ((insn >> (operand->shift))
399 & ((1 << operand->bits) - 1));
401 if ((operand->flags & MN10300_OPERAND_SIGNED) != 0
402 /* These are properly extended by the code above. */
403 && ((operand->flags & MN10300_OPERAND_24BIT) == 0))
404 value = ((value ^ (((unsigned long) 1) << (operand->bits - 1)))
405 - (((unsigned long) 1) << (operand->bits - 1)));
409 || ((operand->flags & MN10300_OPERAND_PAREN) == 0)))
410 (*info->fprintf_func) (info->stream, ",");
414 if ((operand->flags & MN10300_OPERAND_DREG) != 0)
416 value = ((insn >> (operand->shift + extra_shift))
417 & ((1 << operand->bits) - 1));
418 (*info->fprintf_func) (info->stream, "d%d", (int) value);
421 else if ((operand->flags & MN10300_OPERAND_AREG) != 0)
423 value = ((insn >> (operand->shift + extra_shift))
424 & ((1 << operand->bits) - 1));
425 (*info->fprintf_func) (info->stream, "a%d", (int) value);
428 else if ((operand->flags & MN10300_OPERAND_SP) != 0)
429 (*info->fprintf_func) (info->stream, "sp");
431 else if ((operand->flags & MN10300_OPERAND_PSW) != 0)
432 (*info->fprintf_func) (info->stream, "psw");
434 else if ((operand->flags & MN10300_OPERAND_MDR) != 0)
435 (*info->fprintf_func) (info->stream, "mdr");
437 else if ((operand->flags & MN10300_OPERAND_RREG) != 0)
439 value = ((insn >> (operand->shift + extra_shift))
440 & ((1 << operand->bits) - 1));
442 (*info->fprintf_func) (info->stream, "r%d", (int) value);
444 (*info->fprintf_func) (info->stream, "a%d", (int) value - 8);
446 (*info->fprintf_func) (info->stream, "d%d", (int) value - 12);
449 else if ((operand->flags & MN10300_OPERAND_XRREG) != 0)
451 value = ((insn >> (operand->shift + extra_shift))
452 & ((1 << operand->bits) - 1));
454 (*info->fprintf_func) (info->stream, "sp");
456 (*info->fprintf_func) (info->stream, "xr%d", (int) value);
459 else if ((operand->flags & MN10300_OPERAND_FSREG) != 0)
460 (*info->fprintf_func) (info->stream, "fs%d", (int) value);
462 else if ((operand->flags & MN10300_OPERAND_FDREG) != 0)
463 (*info->fprintf_func) (info->stream, "fd%d", (int) value);
465 else if ((operand->flags & MN10300_OPERAND_FPCR) != 0)
466 (*info->fprintf_func) (info->stream, "fpcr");
468 else if ((operand->flags & MN10300_OPERAND_USP) != 0)
469 (*info->fprintf_func) (info->stream, "usp");
471 else if ((operand->flags & MN10300_OPERAND_SSP) != 0)
472 (*info->fprintf_func) (info->stream, "ssp");
474 else if ((operand->flags & MN10300_OPERAND_MSP) != 0)
475 (*info->fprintf_func) (info->stream, "msp");
477 else if ((operand->flags & MN10300_OPERAND_PC) != 0)
478 (*info->fprintf_func) (info->stream, "pc");
480 else if ((operand->flags & MN10300_OPERAND_EPSW) != 0)
481 (*info->fprintf_func) (info->stream, "epsw");
483 else if ((operand->flags & MN10300_OPERAND_PLUS) != 0)
484 (*info->fprintf_func) (info->stream, "+");
486 else if ((operand->flags & MN10300_OPERAND_PAREN) != 0)
489 (*info->fprintf_func) (info->stream, ")");
492 (*info->fprintf_func) (info->stream, "(");
498 else if ((operand->flags & MN10300_OPERAND_PCREL) != 0)
499 (*info->print_address_func) ((long) value + memaddr, info);
501 else if ((operand->flags & MN10300_OPERAND_MEMADDR) != 0)
502 (*info->print_address_func) (value, info);
504 else if ((operand->flags & MN10300_OPERAND_REG_LIST) != 0)
508 (*info->fprintf_func) (info->stream, "[");
511 (*info->fprintf_func) (info->stream, "d2");
518 (*info->fprintf_func) (info->stream, ",");
519 (*info->fprintf_func) (info->stream, "d3");
526 (*info->fprintf_func) (info->stream, ",");
527 (*info->fprintf_func) (info->stream, "a2");
534 (*info->fprintf_func) (info->stream, ",");
535 (*info->fprintf_func) (info->stream, "a3");
542 (*info->fprintf_func) (info->stream, ",");
543 (*info->fprintf_func) (info->stream, "other");
550 (*info->fprintf_func) (info->stream, ",");
551 (*info->fprintf_func) (info->stream, "exreg0");
557 (*info->fprintf_func) (info->stream, ",");
558 (*info->fprintf_func) (info->stream, "exreg1");
564 (*info->fprintf_func) (info->stream, ",");
565 (*info->fprintf_func) (info->stream, "exother");
568 (*info->fprintf_func) (info->stream, "]");
572 (*info->fprintf_func) (info->stream, "%ld", (long) value);
581 /* xgettext:c-format */
582 (*info->fprintf_func) (info->stream, _("unknown\t0x%04lx"), insn);
586 print_insn_mn10300 (bfd_vma memaddr, struct disassemble_info *info)
591 unsigned int consume;
593 /* First figure out how big the opcode is. */
594 status = (*info->read_memory_func) (memaddr, buffer, 1, info);
597 (*info->memory_error_func) (status, memaddr, info);
600 insn = *(unsigned char *) buffer;
602 /* These are one byte insns. */
603 if ((insn & 0xf3) == 0x00
604 || (insn & 0xf0) == 0x10
605 || (insn & 0xfc) == 0x3c
606 || (insn & 0xf3) == 0x41
607 || (insn & 0xf3) == 0x40
608 || (insn & 0xfc) == 0x50
609 || (insn & 0xfc) == 0x54
610 || (insn & 0xf0) == 0x60
611 || (insn & 0xf0) == 0x70
612 || ((insn & 0xf0) == 0x80
613 && (insn & 0x0c) >> 2 != (insn & 0x03))
614 || ((insn & 0xf0) == 0x90
615 && (insn & 0x0c) >> 2 != (insn & 0x03))
616 || ((insn & 0xf0) == 0xa0
617 && (insn & 0x0c) >> 2 != (insn & 0x03))
618 || ((insn & 0xf0) == 0xb0
619 && (insn & 0x0c) >> 2 != (insn & 0x03))
620 || (insn & 0xff) == 0xcb
621 || (insn & 0xfc) == 0xd0
622 || (insn & 0xfc) == 0xd4
623 || (insn & 0xfc) == 0xd8
624 || (insn & 0xf0) == 0xe0
625 || (insn & 0xff) == 0xff)
630 /* These are two byte insns. */
631 else if ((insn & 0xf0) == 0x80
632 || (insn & 0xf0) == 0x90
633 || (insn & 0xf0) == 0xa0
634 || (insn & 0xf0) == 0xb0
635 || (insn & 0xfc) == 0x20
636 || (insn & 0xfc) == 0x28
637 || (insn & 0xf3) == 0x43
638 || (insn & 0xf3) == 0x42
639 || (insn & 0xfc) == 0x58
640 || (insn & 0xfc) == 0x5c
641 || ((insn & 0xf0) == 0xc0
642 && (insn & 0xff) != 0xcb
643 && (insn & 0xff) != 0xcc
644 && (insn & 0xff) != 0xcd)
645 || (insn & 0xff) == 0xf0
646 || (insn & 0xff) == 0xf1
647 || (insn & 0xff) == 0xf2
648 || (insn & 0xff) == 0xf3
649 || (insn & 0xff) == 0xf4
650 || (insn & 0xff) == 0xf5
651 || (insn & 0xff) == 0xf6)
653 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
656 (*info->memory_error_func) (status, memaddr, info);
659 insn = bfd_getb16 (buffer);
663 /* These are three byte insns. */
664 else if ((insn & 0xff) == 0xf8
665 || (insn & 0xff) == 0xcc
666 || (insn & 0xff) == 0xf9
667 || (insn & 0xf3) == 0x01
668 || (insn & 0xf3) == 0x02
669 || (insn & 0xf3) == 0x03
670 || (insn & 0xfc) == 0x24
671 || (insn & 0xfc) == 0x2c
672 || (insn & 0xfc) == 0x30
673 || (insn & 0xfc) == 0x34
674 || (insn & 0xfc) == 0x38
675 || (insn & 0xff) == 0xde
676 || (insn & 0xff) == 0xdf
677 || (insn & 0xff) == 0xf9
678 || (insn & 0xff) == 0xcc)
680 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
683 (*info->memory_error_func) (status, memaddr, info);
686 insn = bfd_getb16 (buffer);
688 status = (*info->read_memory_func) (memaddr + 2, buffer, 1, info);
691 (*info->memory_error_func) (status, memaddr, info);
694 insn |= *(unsigned char *) buffer;
698 /* These are four byte insns. */
699 else if ((insn & 0xff) == 0xfa
700 || (insn & 0xff) == 0xf7
701 || (insn & 0xff) == 0xfb)
703 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
706 (*info->memory_error_func) (status, memaddr, info);
709 insn = bfd_getb32 (buffer);
713 /* These are five byte insns. */
714 else if ((insn & 0xff) == 0xcd
715 || (insn & 0xff) == 0xdc)
717 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
720 (*info->memory_error_func) (status, memaddr, info);
723 insn = bfd_getb32 (buffer);
727 /* These are six byte insns. */
728 else if ((insn & 0xff) == 0xfd
729 || (insn & 0xff) == 0xfc)
731 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
734 (*info->memory_error_func) (status, memaddr, info);
738 insn = bfd_getb32 (buffer);
742 /* Else its a seven byte insns (in theory). */
745 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
748 (*info->memory_error_func) (status, memaddr, info);
752 insn = bfd_getb32 (buffer);
754 /* Handle the 5-byte extended instruction codes. */
755 if ((insn & 0xfff80000) == 0xfe800000)
759 disassemble (memaddr, info, insn, consume);