1 /* s12z-dis.c -- Freescale S12Z disassembly
2 Copyright (C) 2018 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. */
27 #include "opcode/s12z.h"
33 #include "disassemble.h"
36 read_memory (bfd_vma memaddr
, bfd_byte
* buffer
, int size
,
37 struct disassemble_info
* info
)
39 int status
= (*info
->read_memory_func
) (memaddr
, buffer
, size
, info
);
42 (*info
->memory_error_func
) (status
, memaddr
, info
);
48 typedef int (* insn_bytes_f
) (bfd_vma memaddr
,
49 struct disassemble_info
* info
);
51 typedef void (*operands_f
) (bfd_vma memaddr
, struct disassemble_info
* info
);
87 static const struct opr_pb opr_pb
[] = {
88 {0xF0, 0x70, 1, OPR_IMMe4
},
89 {0xF8, 0xB8, 1, OPR_REG
},
90 {0xC0, 0x40, 1, OPR_OFXYS
},
91 {0xEF, 0xE3, 1, OPR_XY_PRE_INC
},
92 {0xEF, 0xE7, 1, OPR_XY_POST_INC
},
93 {0xEF, 0xC3, 1, OPR_XY_PRE_DEC
},
94 {0xEF, 0xC7, 1, OPR_XY_POST_DEC
},
95 {0xFF, 0xFB, 1, OPR_S_PRE_DEC
},
96 {0xFF, 0xFF, 1, OPR_S_POST_INC
},
97 {0xC8, 0x88, 1, OPR_REG_DIRECT
},
98 {0xE8, 0xC8, 1, OPR_REG_INDIRECT
},
100 {0xCE, 0xC0, 2, OPR_IDX_DIRECT
},
101 {0xCE, 0xC4, 2, OPR_IDX_INDIRECT
},
102 {0xC0, 0x00, 2, OPR_EXT1
},
104 {0xC8, 0x80, 3, OPR_IDX2_REG
},
105 {0xFA, 0xF8, 3, OPR_EXT18
},
107 {0xCF, 0xC2, 4, OPR_IDX3_DIRECT
},
108 {0xCF, 0xC6, 4, OPR_IDX3_INDIRECT
},
110 {0xF8, 0xE8, 4, OPR_IDX3_DIRECT_REG
},
111 {0xFF, 0xFA, 4, OPR_EXT3_DIRECT
},
112 {0xFF, 0xFE, 4, OPR_EXT3_INDIRECT
},
116 /* Return the number of bytes in a OPR operand, including the XB postbyte.
117 It does not include any preceeding opcodes. */
119 opr_n_bytes (bfd_vma memaddr
, struct disassemble_info
* info
)
122 int status
= read_memory (memaddr
, &xb
, 1, info
);
127 for (i
= 0; i
< sizeof (opr_pb
) / sizeof (opr_pb
[0]); ++i
)
129 const struct opr_pb
*pb
= opr_pb
+ i
;
130 if ((xb
& pb
->mask
) == pb
->value
)
132 return pb
->n_operands
;
140 opr_n_bytes_p1 (bfd_vma memaddr
, struct disassemble_info
* info
)
142 return 1 + opr_n_bytes (memaddr
, info
);
146 opr_n_bytes2 (bfd_vma memaddr
, struct disassemble_info
* info
)
148 int s
= opr_n_bytes (memaddr
, info
);
149 s
+= opr_n_bytes (memaddr
+ s
, info
);
172 static const struct opr_bb bb_modes
[] =
174 {0x60, 0x00, 2, false, BB_REG_REG_REG
},
175 {0x60, 0x20, 3, false, BB_REG_REG_IMM
},
176 {0x70, 0x40, 2, true, BB_REG_OPR_REG
},
177 {0x70, 0x50, 2, true, BB_OPR_REG_REG
},
178 {0x70, 0x60, 3, true, BB_REG_OPR_IMM
},
179 {0x70, 0x70, 3, true, BB_OPR_REG_IMM
}
183 bfextins_n_bytes (bfd_vma memaddr
, struct disassemble_info
* info
)
186 int status
= read_memory (memaddr
, &bb
, 1, info
);
191 const struct opr_bb
*bbs
= 0;
192 for (i
= 0; i
< sizeof (bb_modes
) / sizeof (bb_modes
[0]); ++i
)
195 if ((bb
& bbs
->mask
) == bbs
->value
)
201 int n
= bbs
->n_operands
;
203 n
+= opr_n_bytes (memaddr
+ n
- 1, info
);
209 single (bfd_vma memaddr ATTRIBUTE_UNUSED
,
210 struct disassemble_info
* info ATTRIBUTE_UNUSED
)
216 two (bfd_vma memaddr ATTRIBUTE_UNUSED
,
217 struct disassemble_info
* info ATTRIBUTE_UNUSED
)
223 three (bfd_vma memaddr ATTRIBUTE_UNUSED
,
224 struct disassemble_info
* info ATTRIBUTE_UNUSED
)
230 four (bfd_vma memaddr ATTRIBUTE_UNUSED
,
231 struct disassemble_info
* info ATTRIBUTE_UNUSED
)
237 five (bfd_vma memaddr ATTRIBUTE_UNUSED
,
238 struct disassemble_info
* info ATTRIBUTE_UNUSED
)
244 pcrel_15bit (bfd_vma memaddr
, struct disassemble_info
* info
)
247 int status
= read_memory (memaddr
, &byte
, 1, info
);
250 return (byte
& 0x80) ? 3 : 2;
257 operand_separator (struct disassemble_info
*info
)
259 if ((info
->flags
& 0x2))
261 (*info
->fprintf_func
) (info
->stream
, ", ");
265 (*info
->fprintf_func
) (info
->stream
, " ");
274 imm1 (bfd_vma memaddr
, struct disassemble_info
* info
)
277 int status
= read_memory (memaddr
, &byte
, 1, info
);
281 operand_separator (info
);
282 (*info
->fprintf_func
) (info
->stream
, "#%d", byte
);
286 trap_decode (bfd_vma memaddr
, struct disassemble_info
* info
)
288 imm1 (memaddr
- 1, info
);
292 const struct reg registers
[S12Z_N_REGISTERS
] =
315 xys_from_postbyte (uint8_t postbyte
)
318 switch ((postbyte
& 0x30) >> 4)
337 xysp_from_postbyte (uint8_t postbyte
)
340 switch ((postbyte
& 0x30) >> 4)
358 /* Render the symbol name whose value is ADDR or the adddress itself if there is
361 decode_possible_symbol (bfd_vma addr
, struct disassemble_info
*info
)
363 if (!info
->symbol_at_address_func (addr
, info
))
365 (*info
->fprintf_func
) (info
->stream
, "%" BFD_VMA_FMT
"d", addr
);
371 for (j
= 0; j
< info
->symtab_size
; ++j
)
373 sym
= info
->symtab
[j
];
374 if (bfd_asymbol_value (sym
) == addr
)
379 if (j
< info
->symtab_size
)
380 (*info
->fprintf_func
) (info
->stream
, "%s", bfd_asymbol_name (sym
));
384 static void ld_18bit_decode (bfd_vma memaddr
, struct disassemble_info
* info
);
387 ext24_decode (bfd_vma memaddr
, struct disassemble_info
* info
)
390 int status
= read_memory (memaddr
, buffer
, 3, info
);
396 for (i
= 0; i
< 3; ++i
)
402 operand_separator (info
);
403 decode_possible_symbol (addr
, info
);
408 decode_signed_value (bfd_vma memaddr
, struct disassemble_info
* info
, short size
)
413 if (0 > read_memory (memaddr
, buffer
, size
, info
))
420 for (i
= 0; i
< size
; ++i
)
422 value
|= buffer
[i
] << (8 * (size
- i
- 1));
425 if (buffer
[0] & 0x80)
427 /* Deal with negative values */
428 value
-= 0x1UL
<< (size
* 8);
435 opr_decode (bfd_vma memaddr
, struct disassemble_info
* info
)
438 int status
= read_memory (memaddr
, &postbyte
, 1, info
);
442 enum OPR_MODE mode
= -1;
444 for (i
= 0; i
< sizeof (opr_pb
) / sizeof (opr_pb
[0]); ++i
)
446 const struct opr_pb
*pb
= opr_pb
+ i
;
447 if ((postbyte
& pb
->mask
) == pb
->value
)
454 operand_separator (info
);
460 uint8_t x
= (postbyte
& 0x0F);
466 (*info
->fprintf_func
) (info
->stream
, "#%d", n
);
471 uint8_t x
= (postbyte
& 0x07);
472 (*info
->fprintf_func
) (info
->stream
, "%s", registers
[x
].name
);
477 const char *reg
= xys_from_postbyte (postbyte
);
478 (*info
->fprintf_func
) (info
->stream
, "(%d,%s)", postbyte
& 0x0F, reg
);
483 (*info
->fprintf_func
) (info
->stream
, "(%s,%s)", registers
[postbyte
& 0x07].name
,
484 xys_from_postbyte (postbyte
));
487 case OPR_REG_INDIRECT
:
489 (*info
->fprintf_func
) (info
->stream
, "[%s,%s]", registers
[postbyte
& 0x07].name
,
490 (postbyte
& 0x10) ? "y": "x");
494 case OPR_IDX_INDIRECT
:
497 read_memory (memaddr
+ 1, &x1
, 1, info
);
502 /* Deal with negative values */
506 (*info
->fprintf_func
) (info
->stream
, "[%d,%s]", idx
,
507 xysp_from_postbyte (postbyte
));
511 case OPR_IDX3_DIRECT
:
514 read_memory (memaddr
+ 1, x
, 3, info
);
515 int idx
= x
[0] << 16 | x
[1] << 8 | x
[2];
519 /* Deal with negative values */
523 (*info
->fprintf_func
) (info
->stream
, "(%d,%s)", idx
,
524 xysp_from_postbyte (postbyte
));
528 case OPR_IDX3_DIRECT_REG
:
531 read_memory (memaddr
+ 1, x
, 3, info
);
532 int idx
= x
[0] << 16 | x
[1] << 8 | x
[2];
536 /* Deal with negative values */
540 (*info
->fprintf_func
) (info
->stream
, "(%d,%s)", idx
,
541 registers
[postbyte
& 0x07].name
);
545 case OPR_IDX3_INDIRECT
:
548 read_memory (memaddr
+ 1, x
, 3, info
);
549 int idx
= x
[0] << 16 | x
[1] << 8 | x
[2];
553 /* Deal with negative values */
557 (*info
->fprintf_func
) (info
->stream
, "[%d,%s]", idx
,
558 xysp_from_postbyte (postbyte
));
565 read_memory (memaddr
+ 1, &x1
, 1, info
);
570 /* Deal with negative values */
574 (*info
->fprintf_func
) (info
->stream
, "(%d,%s)", idx
,
575 xysp_from_postbyte (postbyte
));
582 read_memory (memaddr
+ 1, x
, 2, info
);
583 uint32_t offset
= x
[1] | x
[0] << 8 ;
584 offset
|= (postbyte
& 0x30) << 12;
586 (*info
->fprintf_func
) (info
->stream
, "(%d,%s)", offset
,
587 registers
[postbyte
& 0x07].name
);
593 (*info
->fprintf_func
) (info
->stream
, "(+%s)",
594 (postbyte
& 0x10) ? "y": "x");
598 case OPR_XY_POST_INC
:
600 (*info
->fprintf_func
) (info
->stream
, "(%s+)",
601 (postbyte
& 0x10) ? "y": "x");
607 (*info
->fprintf_func
) (info
->stream
, "(-%s)",
608 (postbyte
& 0x10) ? "y": "x");
612 case OPR_XY_POST_DEC
:
614 (*info
->fprintf_func
) (info
->stream
, "(%s-)",
615 (postbyte
& 0x10) ? "y": "x");
621 (*info
->fprintf_func
) (info
->stream
, "(-s)");
626 (*info
->fprintf_func
) (info
->stream
, "(s+)");
632 const size_t size
= 2;
634 status
= read_memory (memaddr
+ 1, buffer
, size
, info
);
639 for (i
= 0; i
< size
; ++i
)
645 ext18
|= (postbyte
& 0x01) << 16;
646 ext18
|= (postbyte
& 0x04) << 15;
648 decode_possible_symbol (ext18
, info
);
655 read_memory (memaddr
+ 1, &x1
, 1, info
);
658 addr
|= (postbyte
& 0x3f) << 8;
660 decode_possible_symbol (addr
, info
);
664 case OPR_EXT3_DIRECT
:
666 const size_t size
= 3;
668 status
= read_memory (memaddr
+ 1, buffer
, size
, info
);
673 for (i
= 0; i
< size
; ++i
)
675 ext24
|= buffer
[i
] << (8 * (size
- i
- 1));
678 decode_possible_symbol (ext24
, info
);
682 case OPR_EXT3_INDIRECT
:
684 const size_t size
= 3;
686 status
= read_memory (memaddr
+ 1, buffer
, size
, info
);
691 for (i
= 0; i
< size
; ++i
)
693 ext24
|= buffer
[i
] << (8 * (size
- i
- 1));
696 (*info
->fprintf_func
) (info
->stream
, "[%d]", ext24
);
702 (*info
->fprintf_func
) (info
->stream
, "Unknown OPR mode #0x%x (%d)", postbyte
, mode
);
708 opr_decode2 (bfd_vma memaddr
, struct disassemble_info
* info
)
710 int n
= opr_n_bytes (memaddr
, info
);
711 opr_decode (memaddr
, info
);
712 opr_decode (memaddr
+ n
, info
);
716 imm1234 (bfd_vma memaddr
, struct disassemble_info
* info
, int base
)
719 int status
= read_memory (memaddr
- 1, &opcode
, 1, info
);
725 int size
= registers
[opcode
& 0xF].bytes
;
727 uint32_t imm
= decode_signed_value (memaddr
, info
, size
);
728 operand_separator (info
);
729 (*info
->fprintf_func
) (info
->stream
, "#%d", imm
);
733 /* Special case of LD and CMP with register S and IMM operand */
735 reg_s_imm (bfd_vma memaddr
, struct disassemble_info
* info
)
737 operand_separator (info
);
738 (*info
->fprintf_func
) (info
->stream
, "s");
740 uint32_t imm
= decode_signed_value (memaddr
, info
, 3);
741 operand_separator (info
);
742 (*info
->fprintf_func
) (info
->stream
, "#%d", imm
);
745 /* Special case of LD, CMP and ST with register S and OPR operand */
747 reg_s_opr (bfd_vma memaddr
, struct disassemble_info
* info
)
749 operand_separator (info
);
750 (*info
->fprintf_func
) (info
->stream
, "s");
752 opr_decode (memaddr
, info
);
756 imm1234_8base (bfd_vma memaddr
, struct disassemble_info
* info
)
758 imm1234 (memaddr
, info
, 8);
762 imm1234_0base (bfd_vma memaddr
, struct disassemble_info
* info
)
764 imm1234 (memaddr
, info
, 0);
768 tfr (bfd_vma memaddr
, struct disassemble_info
* info
)
771 int status
= read_memory (memaddr
, &byte
, 1, info
);
775 operand_separator (info
);
776 (*info
->fprintf_func
) (info
->stream
, "%s, %s",
777 registers
[byte
>> 4].name
,
778 registers
[byte
& 0xF].name
);
783 reg (bfd_vma memaddr
, struct disassemble_info
* info
)
786 int status
= read_memory (memaddr
- 1, &byte
, 1, info
);
790 operand_separator (info
);
791 (*info
->fprintf_func
) (info
->stream
, "%s", registers
[byte
& 0x07].name
);
795 reg_xy (bfd_vma memaddr
, struct disassemble_info
* info
)
798 int status
= read_memory (memaddr
- 1, &byte
, 1, info
);
802 operand_separator (info
);
803 (*info
->fprintf_func
) (info
->stream
, "%s", (byte
& 0x01) ? "y" : "x");
807 lea_reg_xys_opr (bfd_vma memaddr
, struct disassemble_info
* info
)
810 int status
= read_memory (memaddr
- 1, &byte
, 1, info
);
814 char *reg_xys
= NULL
;
828 operand_separator (info
);
829 (*info
->fprintf_func
) (info
->stream
, "%s", reg_xys
);
830 opr_decode (memaddr
, info
);
836 lea_reg_xys (bfd_vma memaddr
, struct disassemble_info
* info
)
839 int status
= read_memory (memaddr
- 1, &byte
, 1, info
);
843 char *reg_xys
= NULL
;
857 status
= read_memory (memaddr
, &byte
, 1, info
);
863 operand_separator (info
);
864 (*info
->fprintf_func
) (info
->stream
, "%s, (%d,%s)", reg_xys
, v
, reg_xys
);
868 /* PC Relative offsets of size 15 or 7 bits */
870 rel_15_7 (bfd_vma memaddr
, struct disassemble_info
* info
, int offset
)
873 int status
= read_memory (memaddr
, &upper
, 1, info
);
877 bool rel_size
= (upper
& 0x80);
879 int16_t addr
= upper
;
882 /* 15 bits. Get the next byte */
884 status
= read_memory (memaddr
+ 1, &lower
, 1, info
);
892 bool negative
= (addr
& 0x4000);
895 addr
= addr
- 0x4000;
900 bool negative
= (addr
& 0x40);
906 operand_separator (info
);
907 if (!info
->symbol_at_address_func (addr
+ memaddr
- offset
, info
))
909 (*info
->fprintf_func
) (info
->stream
, "*%+d", addr
);
915 for (i
= 0; i
< info
->symtab_size
; ++i
)
917 sym
= info
->symtab
[i
];
918 if (bfd_asymbol_value (sym
) == addr
+ memaddr
- offset
)
923 if (i
< info
->symtab_size
)
924 (*info
->fprintf_func
) (info
->stream
, "%s", bfd_asymbol_name (sym
));
929 /* PC Relative offsets of size 15 or 7 bits */
931 decode_rel_15_7 (bfd_vma memaddr
, struct disassemble_info
* info
)
933 rel_15_7 (memaddr
, info
, 1);
938 const char *mnemonic
;
939 insn_bytes_f insn_bytes
;
941 operands_f operands2
;
944 static int shift_n_bytes (bfd_vma memaddr
, struct disassemble_info
* info
);
945 static int mov_imm_opr_n_bytes (bfd_vma memaddr
, struct disassemble_info
* info
);
946 static int loop_prim_n_bytes (bfd_vma memaddr
, struct disassemble_info
* info
);
947 static void mov_imm_opr (bfd_vma memaddr
, struct disassemble_info
* info
);
948 static void bm_rel_decode (bfd_vma memaddr
, struct disassemble_info
* info
);
949 static int bm_rel_n_bytes (bfd_vma memaddr
, struct disassemble_info
* info
);
950 static int mul_n_bytes (bfd_vma memaddr
, struct disassemble_info
* info
);
951 static void mul_decode (bfd_vma memaddr
, struct disassemble_info
* info
);
952 static int bm_n_bytes (bfd_vma memaddr
, struct disassemble_info
* info
);
953 static void bm_decode (bfd_vma memaddr
, struct disassemble_info
* info
);
956 cmp_xy (bfd_vma memaddr ATTRIBUTE_UNUSED
, struct disassemble_info
* info
)
958 operand_separator (info
);
959 (*info
->fprintf_func
) (info
->stream
, "x, y");
963 sub_d6_x_y (bfd_vma memaddr ATTRIBUTE_UNUSED
, struct disassemble_info
* info
)
965 operand_separator (info
);
966 (*info
->fprintf_func
) (info
->stream
, "d6, x, y");
970 sub_d6_y_x (bfd_vma memaddr ATTRIBUTE_UNUSED
, struct disassemble_info
* info
)
972 operand_separator (info
);
973 (*info
->fprintf_func
) (info
->stream
, "d6, y, x");
976 static const char shift_size_table
[] = {
980 static const struct opcode page2
[] =
982 [0x00] = {"ld", opr_n_bytes_p1
, 0, reg_s_opr
},
983 [0x01] = {"st", opr_n_bytes_p1
, 0, reg_s_opr
},
984 [0x02] = {"cmp", opr_n_bytes_p1
, 0, reg_s_opr
},
985 [0x03] = {"ld", four
, 0, reg_s_imm
},
986 [0x04] = {"cmp", four
, 0, reg_s_imm
},
987 [0x05] = {"stop", single
, 0, 0},
988 [0x06] = {"wai", single
, 0, 0},
989 [0x07] = {"sys", single
, 0, 0},
990 [0x08] = {NULL
, bfextins_n_bytes
, 0, 0}, /* BFEXT / BFINS */
991 [0x09] = {NULL
, bfextins_n_bytes
, 0, 0},
992 [0x0a] = {NULL
, bfextins_n_bytes
, 0, 0},
993 [0x0b] = {NULL
, bfextins_n_bytes
, 0, 0},
994 [0x0c] = {NULL
, bfextins_n_bytes
, 0, 0},
995 [0x0d] = {NULL
, bfextins_n_bytes
, 0, 0},
996 [0x0e] = {NULL
, bfextins_n_bytes
, 0, 0},
997 [0x0f] = {NULL
, bfextins_n_bytes
, 0, 0},
998 [0x10] = {"minu", opr_n_bytes_p1
, reg
, opr_decode
},
999 [0x11] = {"minu", opr_n_bytes_p1
, reg
, opr_decode
},
1000 [0x12] = {"minu", opr_n_bytes_p1
, reg
, opr_decode
},
1001 [0x13] = {"minu", opr_n_bytes_p1
, reg
, opr_decode
},
1002 [0x14] = {"minu", opr_n_bytes_p1
, reg
, opr_decode
},
1003 [0x15] = {"minu", opr_n_bytes_p1
, reg
, opr_decode
},
1004 [0x16] = {"minu", opr_n_bytes_p1
, reg
, opr_decode
},
1005 [0x17] = {"minu", opr_n_bytes_p1
, reg
, opr_decode
},
1006 [0x18] = {"maxu", opr_n_bytes_p1
, reg
, opr_decode
},
1007 [0x19] = {"maxu", opr_n_bytes_p1
, reg
, opr_decode
},
1008 [0x1a] = {"maxu", opr_n_bytes_p1
, reg
, opr_decode
},
1009 [0x1b] = {"maxu", opr_n_bytes_p1
, reg
, opr_decode
},
1010 [0x1c] = {"maxu", opr_n_bytes_p1
, reg
, opr_decode
},
1011 [0x1d] = {"maxu", opr_n_bytes_p1
, reg
, opr_decode
},
1012 [0x1e] = {"maxu", opr_n_bytes_p1
, reg
, opr_decode
},
1013 [0x1f] = {"maxu", opr_n_bytes_p1
, reg
, opr_decode
},
1014 [0x20] = {"mins", opr_n_bytes_p1
, reg
, opr_decode
},
1015 [0x21] = {"mins", opr_n_bytes_p1
, reg
, opr_decode
},
1016 [0x22] = {"mins", opr_n_bytes_p1
, reg
, opr_decode
},
1017 [0x23] = {"mins", opr_n_bytes_p1
, reg
, opr_decode
},
1018 [0x24] = {"mins", opr_n_bytes_p1
, reg
, opr_decode
},
1019 [0x25] = {"mins", opr_n_bytes_p1
, reg
, opr_decode
},
1020 [0x26] = {"mins", opr_n_bytes_p1
, reg
, opr_decode
},
1021 [0x27] = {"mins", opr_n_bytes_p1
, reg
, opr_decode
},
1022 [0x28] = {"maxs", opr_n_bytes_p1
, reg
, opr_decode
},
1023 [0x29] = {"maxs", opr_n_bytes_p1
, reg
, opr_decode
},
1024 [0x2a] = {"maxs", opr_n_bytes_p1
, reg
, opr_decode
},
1025 [0x2b] = {"maxs", opr_n_bytes_p1
, reg
, opr_decode
},
1026 [0x2c] = {"maxs", opr_n_bytes_p1
, reg
, opr_decode
},
1027 [0x2d] = {"maxs", opr_n_bytes_p1
, reg
, opr_decode
},
1028 [0x2e] = {"maxs", opr_n_bytes_p1
, reg
, opr_decode
},
1029 [0x2f] = {"maxs", opr_n_bytes_p1
, reg
, opr_decode
},
1030 [0x30] = {"div", mul_n_bytes
, mul_decode
, 0},
1031 [0x31] = {"div", mul_n_bytes
, mul_decode
, 0},
1032 [0x32] = {"div", mul_n_bytes
, mul_decode
, 0},
1033 [0x33] = {"div", mul_n_bytes
, mul_decode
, 0},
1034 [0x34] = {"div", mul_n_bytes
, mul_decode
, 0},
1035 [0x35] = {"div", mul_n_bytes
, mul_decode
, 0},
1036 [0x36] = {"div", mul_n_bytes
, mul_decode
, 0},
1037 [0x37] = {"div", mul_n_bytes
, mul_decode
, 0},
1038 [0x38] = {"mod", mul_n_bytes
, mul_decode
, 0},
1039 [0x39] = {"mod", mul_n_bytes
, mul_decode
, 0},
1040 [0x3a] = {"mod", mul_n_bytes
, mul_decode
, 0},
1041 [0x3b] = {"mod", mul_n_bytes
, mul_decode
, 0},
1042 [0x3c] = {"mod", mul_n_bytes
, mul_decode
, 0},
1043 [0x3d] = {"mod", mul_n_bytes
, mul_decode
, 0},
1044 [0x3e] = {"mod", mul_n_bytes
, mul_decode
, 0},
1045 [0x3f] = {"mod", mul_n_bytes
, mul_decode
, 0},
1046 [0x40] = {"abs", single
, reg
, 0},
1047 [0x41] = {"abs", single
, reg
, 0},
1048 [0x42] = {"abs", single
, reg
, 0},
1049 [0x43] = {"abs", single
, reg
, 0},
1050 [0x44] = {"abs", single
, reg
, 0},
1051 [0x45] = {"abs", single
, reg
, 0},
1052 [0x46] = {"abs", single
, reg
, 0},
1053 [0x47] = {"abs", single
, reg
, 0},
1054 [0x48] = {"mac", mul_n_bytes
, mul_decode
, 0},
1055 [0x49] = {"mac", mul_n_bytes
, mul_decode
, 0},
1056 [0x4a] = {"mac", mul_n_bytes
, mul_decode
, 0},
1057 [0x4b] = {"mac", mul_n_bytes
, mul_decode
, 0},
1058 [0x4c] = {"mac", mul_n_bytes
, mul_decode
, 0},
1059 [0x4d] = {"mac", mul_n_bytes
, mul_decode
, 0},
1060 [0x4e] = {"mac", mul_n_bytes
, mul_decode
, 0},
1061 [0x4f] = {"mac", mul_n_bytes
, mul_decode
, 0},
1062 [0x50] = {"adc", three
, reg
, imm1234_0base
},
1063 [0x51] = {"adc", three
, reg
, imm1234_0base
},
1064 [0x52] = {"adc", three
, reg
, imm1234_0base
},
1065 [0x53] = {"adc", three
, reg
, imm1234_0base
},
1066 [0x54] = {"adc", two
, reg
, imm1234_0base
},
1067 [0x55] = {"adc", two
, reg
, imm1234_0base
},
1068 [0x56] = {"adc", five
, reg
, imm1234_0base
},
1069 [0x57] = {"adc", five
, reg
, imm1234_0base
},
1070 [0x58] = {"bit", three
, reg
, imm1234_8base
},
1071 [0x59] = {"bit", three
, reg
, imm1234_8base
},
1072 [0x5a] = {"bit", three
, reg
, imm1234_8base
},
1073 [0x5b] = {"bit", three
, reg
, imm1234_8base
},
1074 [0x5c] = {"bit", two
, reg
, imm1234_8base
},
1075 [0x5d] = {"bit", two
, reg
, imm1234_8base
},
1076 [0x5e] = {"bit", five
, reg
, imm1234_8base
},
1077 [0x5f] = {"bit", five
, reg
, imm1234_8base
},
1078 [0x60] = {"adc", opr_n_bytes_p1
, reg
, opr_decode
},
1079 [0x61] = {"adc", opr_n_bytes_p1
, reg
, opr_decode
},
1080 [0x62] = {"adc", opr_n_bytes_p1
, reg
, opr_decode
},
1081 [0x63] = {"adc", opr_n_bytes_p1
, reg
, opr_decode
},
1082 [0x64] = {"adc", opr_n_bytes_p1
, reg
, opr_decode
},
1083 [0x65] = {"adc", opr_n_bytes_p1
, reg
, opr_decode
},
1084 [0x66] = {"adc", opr_n_bytes_p1
, reg
, opr_decode
},
1085 [0x67] = {"adc", opr_n_bytes_p1
, reg
, opr_decode
},
1086 [0x68] = {"bit", opr_n_bytes_p1
, reg
, opr_decode
},
1087 [0x69] = {"bit", opr_n_bytes_p1
, reg
, opr_decode
},
1088 [0x6a] = {"bit", opr_n_bytes_p1
, reg
, opr_decode
},
1089 [0x6b] = {"bit", opr_n_bytes_p1
, reg
, opr_decode
},
1090 [0x6c] = {"bit", opr_n_bytes_p1
, reg
, opr_decode
},
1091 [0x6d] = {"bit", opr_n_bytes_p1
, reg
, opr_decode
},
1092 [0x6e] = {"bit", opr_n_bytes_p1
, reg
, opr_decode
},
1093 [0x6f] = {"bit", opr_n_bytes_p1
, reg
, opr_decode
},
1094 [0x70] = {"sbc", three
, reg
, imm1234_0base
},
1095 [0x71] = {"sbc", three
, reg
, imm1234_0base
},
1096 [0x72] = {"sbc", three
, reg
, imm1234_0base
},
1097 [0x73] = {"sbc", three
, reg
, imm1234_0base
},
1098 [0x74] = {"sbc", two
, reg
, imm1234_0base
},
1099 [0x75] = {"sbc", two
, reg
, imm1234_0base
},
1100 [0x76] = {"sbc", five
, reg
, imm1234_0base
},
1101 [0x77] = {"sbc", five
, reg
, imm1234_0base
},
1102 [0x78] = {"eor", three
, reg
, imm1234_8base
},
1103 [0x79] = {"eor", three
, reg
, imm1234_8base
},
1104 [0x7a] = {"eor", three
, reg
, imm1234_8base
},
1105 [0x7b] = {"eor", three
, reg
, imm1234_8base
},
1106 [0x7c] = {"eor", two
, reg
, imm1234_8base
},
1107 [0x7d] = {"eor", two
, reg
, imm1234_8base
},
1108 [0x7e] = {"eor", five
, reg
, imm1234_8base
},
1109 [0x7f] = {"eor", five
, reg
, imm1234_8base
},
1110 [0x80] = {"sbc", opr_n_bytes_p1
, reg
, opr_decode
},
1111 [0x81] = {"sbc", opr_n_bytes_p1
, reg
, opr_decode
},
1112 [0x82] = {"sbc", opr_n_bytes_p1
, reg
, opr_decode
},
1113 [0x83] = {"sbc", opr_n_bytes_p1
, reg
, opr_decode
},
1114 [0x84] = {"sbc", opr_n_bytes_p1
, reg
, opr_decode
},
1115 [0x85] = {"sbc", opr_n_bytes_p1
, reg
, opr_decode
},
1116 [0x86] = {"sbc", opr_n_bytes_p1
, reg
, opr_decode
},
1117 [0x87] = {"sbc", opr_n_bytes_p1
, reg
, opr_decode
},
1118 [0x88] = {"eor", opr_n_bytes_p1
, reg
, opr_decode
},
1119 [0x89] = {"eor", opr_n_bytes_p1
, reg
, opr_decode
},
1120 [0x8a] = {"eor", opr_n_bytes_p1
, reg
, opr_decode
},
1121 [0x8b] = {"eor", opr_n_bytes_p1
, reg
, opr_decode
},
1122 [0x8c] = {"eor", opr_n_bytes_p1
, reg
, opr_decode
},
1123 [0x8d] = {"eor", opr_n_bytes_p1
, reg
, opr_decode
},
1124 [0x8e] = {"eor", opr_n_bytes_p1
, reg
, opr_decode
},
1125 [0x8f] = {"eor", opr_n_bytes_p1
, reg
, opr_decode
},
1126 [0x90] = {"rti", single
, 0, 0},
1127 [0x91] = {"clb", two
, tfr
, 0},
1128 [0x92] = {"trap", single
, trap_decode
, 0},
1129 [0x93] = {"trap", single
, trap_decode
, 0},
1130 [0x94] = {"trap", single
, trap_decode
, 0},
1131 [0x95] = {"trap", single
, trap_decode
, 0},
1132 [0x96] = {"trap", single
, trap_decode
, 0},
1133 [0x97] = {"trap", single
, trap_decode
, 0},
1134 [0x98] = {"trap", single
, trap_decode
, 0},
1135 [0x99] = {"trap", single
, trap_decode
, 0},
1136 [0x9a] = {"trap", single
, trap_decode
, 0},
1137 [0x9b] = {"trap", single
, trap_decode
, 0},
1138 [0x9c] = {"trap", single
, trap_decode
, 0},
1139 [0x9d] = {"trap", single
, trap_decode
, 0},
1140 [0x9e] = {"trap", single
, trap_decode
, 0},
1141 [0x9f] = {"trap", single
, trap_decode
, 0},
1142 [0xa0] = {"sat", single
, reg
, 0},
1143 [0xa1] = {"sat", single
, reg
, 0},
1144 [0xa2] = {"sat", single
, reg
, 0},
1145 [0xa3] = {"sat", single
, reg
, 0},
1146 [0xa4] = {"sat", single
, reg
, 0},
1147 [0xa5] = {"sat", single
, reg
, 0},
1148 [0xa6] = {"sat", single
, reg
, 0},
1149 [0xa7] = {"sat", single
, reg
, 0},
1150 [0xa8] = {"trap", single
, trap_decode
, 0},
1151 [0xa9] = {"trap", single
, trap_decode
, 0},
1152 [0xaa] = {"trap", single
, trap_decode
, 0},
1153 [0xab] = {"trap", single
, trap_decode
, 0},
1154 [0xac] = {"trap", single
, trap_decode
, 0},
1155 [0xad] = {"trap", single
, trap_decode
, 0},
1156 [0xae] = {"trap", single
, trap_decode
, 0},
1157 [0xaf] = {"trap", single
, trap_decode
, 0},
1158 [0xb0] = {"qmul", mul_n_bytes
, mul_decode
, 0},
1159 [0xb1] = {"qmul", mul_n_bytes
, mul_decode
, 0},
1160 [0xb2] = {"qmul", mul_n_bytes
, mul_decode
, 0},
1161 [0xb3] = {"qmul", mul_n_bytes
, mul_decode
, 0},
1162 [0xb4] = {"qmul", mul_n_bytes
, mul_decode
, 0},
1163 [0xb5] = {"qmul", mul_n_bytes
, mul_decode
, 0},
1164 [0xb6] = {"qmul", mul_n_bytes
, mul_decode
, 0},
1165 [0xb7] = {"qmul", mul_n_bytes
, mul_decode
, 0},
1166 [0xb8] = {"trap", single
, trap_decode
, 0},
1167 [0xb9] = {"trap", single
, trap_decode
, 0},
1168 [0xba] = {"trap", single
, trap_decode
, 0},
1169 [0xbb] = {"trap", single
, trap_decode
, 0},
1170 [0xbc] = {"trap", single
, trap_decode
, 0},
1171 [0xbd] = {"trap", single
, trap_decode
, 0},
1172 [0xbe] = {"trap", single
, trap_decode
, 0},
1173 [0xbf] = {"trap", single
, trap_decode
, 0},
1174 [0xc0] = {"trap", single
, trap_decode
, 0},
1175 [0xc1] = {"trap", single
, trap_decode
, 0},
1176 [0xc2] = {"trap", single
, trap_decode
, 0},
1177 [0xc3] = {"trap", single
, trap_decode
, 0},
1178 [0xc4] = {"trap", single
, trap_decode
, 0},
1179 [0xc5] = {"trap", single
, trap_decode
, 0},
1180 [0xc6] = {"trap", single
, trap_decode
, 0},
1181 [0xc7] = {"trap", single
, trap_decode
, 0},
1182 [0xc8] = {"trap", single
, trap_decode
, 0},
1183 [0xc9] = {"trap", single
, trap_decode
, 0},
1184 [0xca] = {"trap", single
, trap_decode
, 0},
1185 [0xcb] = {"trap", single
, trap_decode
, 0},
1186 [0xcc] = {"trap", single
, trap_decode
, 0},
1187 [0xcd] = {"trap", single
, trap_decode
, 0},
1188 [0xce] = {"trap", single
, trap_decode
, 0},
1189 [0xcf] = {"trap", single
, trap_decode
, 0},
1190 [0xd0] = {"trap", single
, trap_decode
, 0},
1191 [0xd1] = {"trap", single
, trap_decode
, 0},
1192 [0xd2] = {"trap", single
, trap_decode
, 0},
1193 [0xd3] = {"trap", single
, trap_decode
, 0},
1194 [0xd4] = {"trap", single
, trap_decode
, 0},
1195 [0xd5] = {"trap", single
, trap_decode
, 0},
1196 [0xd6] = {"trap", single
, trap_decode
, 0},
1197 [0xd7] = {"trap", single
, trap_decode
, 0},
1198 [0xd8] = {"trap", single
, trap_decode
, 0},
1199 [0xd9] = {"trap", single
, trap_decode
, 0},
1200 [0xda] = {"trap", single
, trap_decode
, 0},
1201 [0xdb] = {"trap", single
, trap_decode
, 0},
1202 [0xdc] = {"trap", single
, trap_decode
, 0},
1203 [0xdd] = {"trap", single
, trap_decode
, 0},
1204 [0xde] = {"trap", single
, trap_decode
, 0},
1205 [0xdf] = {"trap", single
, trap_decode
, 0},
1206 [0xe0] = {"trap", single
, trap_decode
, 0},
1207 [0xe1] = {"trap", single
, trap_decode
, 0},
1208 [0xe2] = {"trap", single
, trap_decode
, 0},
1209 [0xe3] = {"trap", single
, trap_decode
, 0},
1210 [0xe4] = {"trap", single
, trap_decode
, 0},
1211 [0xe5] = {"trap", single
, trap_decode
, 0},
1212 [0xe6] = {"trap", single
, trap_decode
, 0},
1213 [0xe7] = {"trap", single
, trap_decode
, 0},
1214 [0xe8] = {"trap", single
, trap_decode
, 0},
1215 [0xe9] = {"trap", single
, trap_decode
, 0},
1216 [0xea] = {"trap", single
, trap_decode
, 0},
1217 [0xeb] = {"trap", single
, trap_decode
, 0},
1218 [0xec] = {"trap", single
, trap_decode
, 0},
1219 [0xed] = {"trap", single
, trap_decode
, 0},
1220 [0xee] = {"trap", single
, trap_decode
, 0},
1221 [0xef] = {"trap", single
, trap_decode
, 0},
1222 [0xf0] = {"trap", single
, trap_decode
, 0},
1223 [0xf1] = {"trap", single
, trap_decode
, 0},
1224 [0xf2] = {"trap", single
, trap_decode
, 0},
1225 [0xf3] = {"trap", single
, trap_decode
, 0},
1226 [0xf4] = {"trap", single
, trap_decode
, 0},
1227 [0xf5] = {"trap", single
, trap_decode
, 0},
1228 [0xf6] = {"trap", single
, trap_decode
, 0},
1229 [0xf7] = {"trap", single
, trap_decode
, 0},
1230 [0xf8] = {"trap", single
, trap_decode
, 0},
1231 [0xf9] = {"trap", single
, trap_decode
, 0},
1232 [0xfa] = {"trap", single
, trap_decode
, 0},
1233 [0xfb] = {"trap", single
, trap_decode
, 0},
1234 [0xfc] = {"trap", single
, trap_decode
, 0},
1235 [0xfd] = {"trap", single
, trap_decode
, 0},
1236 [0xfe] = {"trap", single
, trap_decode
, 0},
1237 [0xff] = {"trap", single
, trap_decode
, 0},
1240 static const struct opcode page1
[] =
1242 [0x00] = {"bgnd", single
, 0, 0},
1243 [0x01] = {"nop", single
, 0, 0},
1244 [0x02] = {"brclr", bm_rel_n_bytes
, bm_rel_decode
, 0},
1245 [0x03] = {"brset", bm_rel_n_bytes
, bm_rel_decode
, 0},
1246 [0x04] = {NULL
, two
, 0, 0}, /* psh/pul */
1247 [0x05] = {"rts", single
, 0, 0},
1248 [0x06] = {"lea", opr_n_bytes_p1
, reg
, opr_decode
},
1249 [0x07] = {"lea", opr_n_bytes_p1
, reg
, opr_decode
},
1250 [0x08] = {"lea", opr_n_bytes_p1
, lea_reg_xys_opr
, 0},
1251 [0x09] = {"lea", opr_n_bytes_p1
, lea_reg_xys_opr
, 0},
1252 [0x0a] = {"lea", opr_n_bytes_p1
, lea_reg_xys_opr
, 0},
1253 [0x0b] = {NULL
, loop_prim_n_bytes
, 0, 0}, /* Loop primitives TBcc / DBcc */
1254 [0x0c] = {"mov.b", mov_imm_opr_n_bytes
, mov_imm_opr
, 0},
1255 [0x0d] = {"mov.w", mov_imm_opr_n_bytes
, mov_imm_opr
, 0},
1256 [0x0e] = {"mov.p", mov_imm_opr_n_bytes
, mov_imm_opr
, 0},
1257 [0x0f] = {"mov.l", mov_imm_opr_n_bytes
, mov_imm_opr
, 0},
1258 [0x10] = {NULL
, shift_n_bytes
, 0, 0}, /* lsr/lsl/asl/asr/rol/ror */
1259 [0x11] = {NULL
, shift_n_bytes
, 0, 0},
1260 [0x12] = {NULL
, shift_n_bytes
, 0, 0},
1261 [0x13] = {NULL
, shift_n_bytes
, 0, 0},
1262 [0x14] = {NULL
, shift_n_bytes
, 0, 0},
1263 [0x15] = {NULL
, shift_n_bytes
, 0, 0},
1264 [0x16] = {NULL
, shift_n_bytes
, 0, 0},
1265 [0x17] = {NULL
, shift_n_bytes
, 0, 0},
1266 [0x18] = {"lea", two
, lea_reg_xys
, NULL
},
1267 [0x19] = {"lea", two
, lea_reg_xys
, NULL
},
1268 [0x1a] = {"lea", two
, lea_reg_xys
, NULL
},
1270 [0x1c] = {"mov.b", opr_n_bytes2
, 0, opr_decode2
},
1271 [0x1d] = {"mov.w", opr_n_bytes2
, 0, opr_decode2
},
1272 [0x1e] = {"mov.p", opr_n_bytes2
, 0, opr_decode2
},
1273 [0x1f] = {"mov.l", opr_n_bytes2
, 0, opr_decode2
},
1274 [0x20] = {"bra", pcrel_15bit
, decode_rel_15_7
, 0},
1275 [0x21] = {"bsr", pcrel_15bit
, decode_rel_15_7
, 0},
1276 [0x22] = {"bhi", pcrel_15bit
, decode_rel_15_7
, 0},
1277 [0x23] = {"bls", pcrel_15bit
, decode_rel_15_7
, 0},
1278 [0x24] = {"bcc", pcrel_15bit
, decode_rel_15_7
, 0},
1279 [0x25] = {"bcs", pcrel_15bit
, decode_rel_15_7
, 0},
1280 [0x26] = {"bne", pcrel_15bit
, decode_rel_15_7
, 0},
1281 [0x27] = {"beq", pcrel_15bit
, decode_rel_15_7
, 0},
1282 [0x28] = {"bvc", pcrel_15bit
, decode_rel_15_7
, 0},
1283 [0x29] = {"bvs", pcrel_15bit
, decode_rel_15_7
, 0},
1284 [0x2a] = {"bpl", pcrel_15bit
, decode_rel_15_7
, 0},
1285 [0x2b] = {"bmi", pcrel_15bit
, decode_rel_15_7
, 0},
1286 [0x2c] = {"bge", pcrel_15bit
, decode_rel_15_7
, 0},
1287 [0x2d] = {"blt", pcrel_15bit
, decode_rel_15_7
, 0},
1288 [0x2e] = {"bgt", pcrel_15bit
, decode_rel_15_7
, 0},
1289 [0x2f] = {"ble", pcrel_15bit
, decode_rel_15_7
, 0},
1290 [0x30] = {"inc", single
, reg
, 0},
1291 [0x31] = {"inc", single
, reg
, 0},
1292 [0x32] = {"inc", single
, reg
, 0},
1293 [0x33] = {"inc", single
, reg
, 0},
1294 [0x34] = {"inc", single
, reg
, 0},
1295 [0x35] = {"inc", single
, reg
, 0},
1296 [0x36] = {"inc", single
, reg
, 0},
1297 [0x37] = {"inc", single
, reg
, 0},
1298 [0x38] = {"clr", single
, reg
, 0},
1299 [0x39] = {"clr", single
, reg
, 0},
1300 [0x3a] = {"clr", single
, reg
, 0},
1301 [0x3b] = {"clr", single
, reg
, 0},
1302 [0x3c] = {"clr", single
, reg
, 0},
1303 [0x3d] = {"clr", single
, reg
, 0},
1304 [0x3e] = {"clr", single
, reg
, 0},
1305 [0x3f] = {"clr", single
, reg
, 0},
1306 [0x40] = {"dec", single
, reg
, 0},
1307 [0x41] = {"dec", single
, reg
, 0},
1308 [0x42] = {"dec", single
, reg
, 0},
1309 [0x43] = {"dec", single
, reg
, 0},
1310 [0x44] = {"dec", single
, reg
, 0},
1311 [0x45] = {"dec", single
, reg
, 0},
1312 [0x46] = {"dec", single
, reg
, 0},
1313 [0x47] = {"dec", single
, reg
, 0},
1314 [0x48] = {"mul", mul_n_bytes
, mul_decode
, 0},
1315 [0x49] = {"mul", mul_n_bytes
, mul_decode
, 0},
1316 [0x4a] = {"mul", mul_n_bytes
, mul_decode
, 0},
1317 [0x4b] = {"mul", mul_n_bytes
, mul_decode
, 0},
1318 [0x4c] = {"mul", mul_n_bytes
, mul_decode
, 0},
1319 [0x4d] = {"mul", mul_n_bytes
, mul_decode
, 0},
1320 [0x4e] = {"mul", mul_n_bytes
, mul_decode
, 0},
1321 [0x4f] = {"mul", mul_n_bytes
, mul_decode
, 0},
1322 [0x50] = {"add", three
, reg
, imm1234_0base
},
1323 [0x51] = {"add", three
, reg
, imm1234_0base
},
1324 [0x52] = {"add", three
, reg
, imm1234_0base
},
1325 [0x53] = {"add", three
, reg
, imm1234_0base
},
1326 [0x54] = {"add", two
, reg
, imm1234_0base
},
1327 [0x55] = {"add", two
, reg
, imm1234_0base
},
1328 [0x56] = {"add", five
, reg
, imm1234_0base
},
1329 [0x57] = {"add", five
, reg
, imm1234_0base
},
1330 [0x58] = {"and", three
, reg
, imm1234_8base
},
1331 [0x59] = {"and", three
, reg
, imm1234_8base
},
1332 [0x5a] = {"and", three
, reg
, imm1234_8base
},
1333 [0x5b] = {"and", three
, reg
, imm1234_8base
},
1334 [0x5c] = {"and", two
, reg
, imm1234_8base
},
1335 [0x5d] = {"and", two
, reg
, imm1234_8base
},
1336 [0x5e] = {"and", five
, reg
, imm1234_8base
},
1337 [0x5f] = {"and", five
, reg
, imm1234_8base
},
1338 [0x60] = {"add", opr_n_bytes_p1
, reg
, opr_decode
},
1339 [0x61] = {"add", opr_n_bytes_p1
, reg
, opr_decode
},
1340 [0x62] = {"add", opr_n_bytes_p1
, reg
, opr_decode
},
1341 [0x63] = {"add", opr_n_bytes_p1
, reg
, opr_decode
},
1342 [0x64] = {"add", opr_n_bytes_p1
, reg
, opr_decode
},
1343 [0x65] = {"add", opr_n_bytes_p1
, reg
, opr_decode
},
1344 [0x66] = {"add", opr_n_bytes_p1
, reg
, opr_decode
},
1345 [0x67] = {"add", opr_n_bytes_p1
, reg
, opr_decode
},
1346 [0x68] = {"and", opr_n_bytes_p1
, reg
, opr_decode
},
1347 [0x69] = {"and", opr_n_bytes_p1
, reg
, opr_decode
},
1348 [0x6a] = {"and", opr_n_bytes_p1
, reg
, opr_decode
},
1349 [0x6b] = {"and", opr_n_bytes_p1
, reg
, opr_decode
},
1350 [0x6c] = {"and", opr_n_bytes_p1
, reg
, opr_decode
},
1351 [0x6d] = {"and", opr_n_bytes_p1
, reg
, opr_decode
},
1352 [0x6e] = {"and", opr_n_bytes_p1
, reg
, opr_decode
},
1353 [0x6f] = {"and", opr_n_bytes_p1
, reg
, opr_decode
},
1354 [0x70] = {"sub", three
, reg
, imm1234_0base
},
1355 [0x71] = {"sub", three
, reg
, imm1234_0base
},
1356 [0x72] = {"sub", three
, reg
, imm1234_0base
},
1357 [0x73] = {"sub", three
, reg
, imm1234_0base
},
1358 [0x74] = {"sub", two
, reg
, imm1234_0base
},
1359 [0x75] = {"sub", two
, reg
, imm1234_0base
},
1360 [0x76] = {"sub", five
, reg
, imm1234_0base
},
1361 [0x77] = {"sub", five
, reg
, imm1234_0base
},
1362 [0x78] = {"or", three
, reg
, imm1234_8base
},
1363 [0x79] = {"or", three
, reg
, imm1234_8base
},
1364 [0x7a] = {"or", three
, reg
, imm1234_8base
},
1365 [0x7b] = {"or", three
, reg
, imm1234_8base
},
1366 [0x7c] = {"or", two
, reg
, imm1234_8base
},
1367 [0x7d] = {"or", two
, reg
, imm1234_8base
},
1368 [0x7e] = {"or", five
, reg
, imm1234_8base
},
1369 [0x7f] = {"or", five
, reg
, imm1234_8base
},
1370 [0x80] = {"sub", opr_n_bytes_p1
, reg
, opr_decode
},
1371 [0x81] = {"sub", opr_n_bytes_p1
, reg
, opr_decode
},
1372 [0x82] = {"sub", opr_n_bytes_p1
, reg
, opr_decode
},
1373 [0x83] = {"sub", opr_n_bytes_p1
, reg
, opr_decode
},
1374 [0x84] = {"sub", opr_n_bytes_p1
, reg
, opr_decode
},
1375 [0x85] = {"sub", opr_n_bytes_p1
, reg
, opr_decode
},
1376 [0x86] = {"sub", opr_n_bytes_p1
, reg
, opr_decode
},
1377 [0x87] = {"sub", opr_n_bytes_p1
, reg
, opr_decode
},
1378 [0x88] = {"or", opr_n_bytes_p1
, reg
, opr_decode
},
1379 [0x89] = {"or", opr_n_bytes_p1
, reg
, opr_decode
},
1380 [0x8a] = {"or", opr_n_bytes_p1
, reg
, opr_decode
},
1381 [0x8b] = {"or", opr_n_bytes_p1
, reg
, opr_decode
},
1382 [0x8c] = {"or", opr_n_bytes_p1
, reg
, opr_decode
},
1383 [0x8d] = {"or", opr_n_bytes_p1
, reg
, opr_decode
},
1384 [0x8e] = {"or", opr_n_bytes_p1
, reg
, opr_decode
},
1385 [0x8f] = {"or", opr_n_bytes_p1
, reg
, opr_decode
},
1386 [0x90] = {"ld", three
, reg
, imm1234_0base
},
1387 [0x91] = {"ld", three
, reg
, imm1234_0base
},
1388 [0x92] = {"ld", three
, reg
, imm1234_0base
},
1389 [0x93] = {"ld", three
, reg
, imm1234_0base
},
1390 [0x94] = {"ld", two
, reg
, imm1234_0base
},
1391 [0x95] = {"ld", two
, reg
, imm1234_0base
},
1392 [0x96] = {"ld", five
, reg
, imm1234_0base
},
1393 [0x97] = {"ld", five
, reg
, imm1234_0base
},
1394 [0x98] = {"ld", four
, reg_xy
, imm1234_0base
},
1395 [0x99] = {"ld", four
, reg_xy
, imm1234_0base
},
1396 [0x9a] = {"clr", single
, reg_xy
, 0},
1397 [0x9b] = {"clr", single
, reg_xy
, 0},
1398 [0x9c] = {"inc.b", opr_n_bytes_p1
, 0, opr_decode
},
1399 [0x9d] = {"inc.w", opr_n_bytes_p1
, 0, opr_decode
},
1400 [0x9e] = {"tfr", two
, tfr
, NULL
},
1401 [0x9f] = {"inc.l", opr_n_bytes_p1
, 0, opr_decode
},
1402 [0xa0] = {"ld", opr_n_bytes_p1
, reg
, opr_decode
},
1403 [0xa1] = {"ld", opr_n_bytes_p1
, reg
, opr_decode
},
1404 [0xa2] = {"ld", opr_n_bytes_p1
, reg
, opr_decode
},
1405 [0xa3] = {"ld", opr_n_bytes_p1
, reg
, opr_decode
},
1406 [0xa4] = {"ld", opr_n_bytes_p1
, reg
, opr_decode
},
1407 [0xa5] = {"ld", opr_n_bytes_p1
, reg
, opr_decode
},
1408 [0xa6] = {"ld", opr_n_bytes_p1
, reg
, opr_decode
},
1409 [0xa7] = {"ld", opr_n_bytes_p1
, reg
, opr_decode
},
1410 [0xa8] = {"ld", opr_n_bytes_p1
, reg_xy
, opr_decode
},
1411 [0xa9] = {"ld", opr_n_bytes_p1
, reg_xy
, opr_decode
},
1412 [0xaa] = {"jmp", opr_n_bytes_p1
, opr_decode
, 0},
1413 [0xab] = {"jsr", opr_n_bytes_p1
, opr_decode
, 0},
1414 [0xac] = {"dec.b", opr_n_bytes_p1
, 0, opr_decode
},
1415 [0xad] = {"dec.w", opr_n_bytes_p1
, 0, opr_decode
},
1416 [0xae] = {NULL
, two
, 0, 0}, /* EXG / SEX */
1417 [0xaf] = {"dec.l", opr_n_bytes_p1
, 0, opr_decode
},
1418 [0xb0] = {"ld", four
, reg
, ext24_decode
},
1419 [0xb1] = {"ld", four
, reg
, ext24_decode
},
1420 [0xb2] = {"ld", four
, reg
, ext24_decode
},
1421 [0xb3] = {"ld", four
, reg
, ext24_decode
},
1422 [0xb4] = {"ld", four
, reg
, ext24_decode
},
1423 [0xb5] = {"ld", four
, reg
, ext24_decode
},
1424 [0xb6] = {"ld", four
, reg
, ext24_decode
},
1425 [0xb7] = {"ld", four
, reg
, ext24_decode
},
1426 [0xb8] = {"ld", four
, reg_xy
, ext24_decode
},
1427 [0xb9] = {"ld", four
, reg_xy
, ext24_decode
},
1428 [0xba] = {"jmp", four
, ext24_decode
, 0},
1429 [0xbb] = {"jsr", four
, ext24_decode
, 0},
1430 [0xbc] = {"clr.b", opr_n_bytes_p1
, 0, opr_decode
},
1431 [0xbd] = {"clr.w", opr_n_bytes_p1
, 0, opr_decode
},
1432 [0xbe] = {"clr.p", opr_n_bytes_p1
, 0, opr_decode
},
1433 [0xbf] = {"clr.l", opr_n_bytes_p1
, 0, opr_decode
},
1434 [0xc0] = {"st", opr_n_bytes_p1
, reg
, opr_decode
},
1435 [0xc1] = {"st", opr_n_bytes_p1
, reg
, opr_decode
},
1436 [0xc2] = {"st", opr_n_bytes_p1
, reg
, opr_decode
},
1437 [0xc3] = {"st", opr_n_bytes_p1
, reg
, opr_decode
},
1438 [0xc4] = {"st", opr_n_bytes_p1
, reg
, opr_decode
},
1439 [0xc5] = {"st", opr_n_bytes_p1
, reg
, opr_decode
},
1440 [0xc6] = {"st", opr_n_bytes_p1
, reg
, opr_decode
},
1441 [0xc7] = {"st", opr_n_bytes_p1
, reg
, opr_decode
},
1442 [0xc8] = {"st", opr_n_bytes_p1
, reg_xy
, opr_decode
},
1443 [0xc9] = {"st", opr_n_bytes_p1
, reg_xy
, opr_decode
},
1444 [0xca] = {"ld", three
, reg_xy
, ld_18bit_decode
},
1445 [0xcb] = {"ld", three
, reg_xy
, ld_18bit_decode
},
1446 [0xcc] = {"com.b", opr_n_bytes_p1
, NULL
, opr_decode
},
1447 [0xcd] = {"com.w", opr_n_bytes_p1
, NULL
, opr_decode
},
1448 [0xce] = {"andcc", two
, imm1
, 0},
1449 [0xcf] = {"com.l", opr_n_bytes_p1
, NULL
, opr_decode
},
1450 [0xd0] = {"st", four
, reg
, ext24_decode
},
1451 [0xd1] = {"st", four
, reg
, ext24_decode
},
1452 [0xd2] = {"st", four
, reg
, ext24_decode
},
1453 [0xd3] = {"st", four
, reg
, ext24_decode
},
1454 [0xd4] = {"st", four
, reg
, ext24_decode
},
1455 [0xd5] = {"st", four
, reg
, ext24_decode
},
1456 [0xd6] = {"st", four
, reg
, ext24_decode
},
1457 [0xd7] = {"st", four
, reg
, ext24_decode
},
1458 [0xd8] = {"st", four
, reg_xy
, ext24_decode
},
1459 [0xd9] = {"st", four
, reg_xy
, ext24_decode
},
1460 [0xda] = {"ld", three
, reg_xy
, ld_18bit_decode
},
1461 [0xdb] = {"ld", three
, reg_xy
, ld_18bit_decode
},
1462 [0xdc] = {"neg.b", opr_n_bytes_p1
, NULL
, opr_decode
},
1463 [0xdd] = {"neg.w", opr_n_bytes_p1
, NULL
, opr_decode
},
1464 [0xde] = {"orcc", two
, imm1
, 0},
1465 [0xdf] = {"neg.l", opr_n_bytes_p1
, NULL
, opr_decode
},
1466 [0xe0] = {"cmp", three
, reg
, imm1234_0base
},
1467 [0xe1] = {"cmp", three
, reg
, imm1234_0base
},
1468 [0xe2] = {"cmp", three
, reg
, imm1234_0base
},
1469 [0xe3] = {"cmp", three
, reg
, imm1234_0base
},
1470 [0xe4] = {"cmp", two
, reg
, imm1234_0base
},
1471 [0xe5] = {"cmp", two
, reg
, imm1234_0base
},
1472 [0xe6] = {"cmp", five
, reg
, imm1234_0base
},
1473 [0xe7] = {"cmp", five
, reg
, imm1234_0base
},
1474 [0xe8] = {"cmp", four
, reg_xy
, imm1234_0base
},
1475 [0xe9] = {"cmp", four
, reg_xy
, imm1234_0base
},
1476 [0xea] = {"ld", three
, reg_xy
, ld_18bit_decode
},
1477 [0xeb] = {"ld", three
, reg_xy
, ld_18bit_decode
},
1478 [0xec] = {"bclr", bm_n_bytes
, bm_decode
, 0},
1479 [0xed] = {"bset", bm_n_bytes
, bm_decode
, 0},
1480 [0xee] = {"btgl", bm_n_bytes
, bm_decode
, 0},
1481 [0xef] = {"!!invalid!!", NULL
, NULL
, NULL
}, /* SPARE */
1482 [0xf0] = {"cmp", opr_n_bytes_p1
, reg
, opr_decode
},
1483 [0xf1] = {"cmp", opr_n_bytes_p1
, reg
, opr_decode
},
1484 [0xf2] = {"cmp", opr_n_bytes_p1
, reg
, opr_decode
},
1485 [0xf3] = {"cmp", opr_n_bytes_p1
, reg
, opr_decode
},
1486 [0xf4] = {"cmp", opr_n_bytes_p1
, reg
, opr_decode
},
1487 [0xf5] = {"cmp", opr_n_bytes_p1
, reg
, opr_decode
},
1488 [0xf6] = {"cmp", opr_n_bytes_p1
, reg
, opr_decode
},
1489 [0xf7] = {"cmp", opr_n_bytes_p1
, reg
, opr_decode
},
1490 [0xf8] = {"cmp", opr_n_bytes_p1
, reg_xy
, opr_decode
},
1491 [0xf9] = {"cmp", opr_n_bytes_p1
, reg_xy
, opr_decode
},
1492 [0xfa] = {"ld", three
, reg_xy
, ld_18bit_decode
},
1493 [0xfb] = {"ld", three
, reg_xy
, ld_18bit_decode
},
1494 [0xfc] = {"cmp", single
, cmp_xy
, 0},
1495 [0xfd] = {"sub", single
, sub_d6_x_y
, 0},
1496 [0xfe] = {"sub", single
, sub_d6_y_x
, 0},
1497 [0xff] = {"swi", single
, 0, 0}
1501 static const char *oprregs1
[] =
1503 "d3", "d2", "d1", "d0", "ccl", "cch"
1506 static const char *oprregs2
[] =
1508 "y", "x", "d7", "d6", "d5", "d4"
1529 static const struct mb mul_table
[] = {
1530 {0x40, 0x00, MUL_REG_REG
},
1532 {0x47, 0x40, MUL_REG_OPR
},
1533 {0x47, 0x41, MUL_REG_OPR
},
1534 {0x47, 0x43, MUL_REG_OPR
},
1536 {0x47, 0x44, MUL_REG_IMM
},
1537 {0x47, 0x45, MUL_REG_IMM
},
1538 {0x47, 0x47, MUL_REG_IMM
},
1540 {0x43, 0x42, MUL_OPR_OPR
},
1544 mul_decode (bfd_vma memaddr
, struct disassemble_info
* info
)
1547 int status
= read_memory (memaddr
, &mb
, 1, info
);
1553 status
= read_memory (memaddr
- 1, &byte
, 1, info
);
1557 (*info
->fprintf_func
) (info
->stream
, "%c", (mb
& 0x80) ? 's' : 'u');
1559 enum MUL_MODE mode
= -1;
1561 for (i
= 0; i
< sizeof (mul_table
) / sizeof (mul_table
[0]); ++i
)
1563 const struct mb
*mm
= mul_table
+ i
;
1564 if ((mb
& mm
->mask
) == mm
->value
)
1577 int size1
= (mb
& 0x30) >> 4;
1578 int size2
= (mb
& 0x0c) >> 2;
1579 (*info
->fprintf_func
) (info
->stream
, ".%c%c",
1580 shift_size_table
[size1
],
1581 shift_size_table
[size2
]);
1586 int size
= (mb
& 0x3);
1587 (*info
->fprintf_func
) (info
->stream
, ".%c", shift_size_table
[size
]);
1592 operand_separator (info
);
1593 (*info
->fprintf_func
) (info
->stream
, "%s", registers
[byte
& 0x7].name
);
1600 operand_separator (info
);
1601 (*info
->fprintf_func
) (info
->stream
, "%s", registers
[(mb
& 0x38) >> 3].name
);
1610 operand_separator (info
);
1611 int size
= (mb
& 0x3);
1612 uint32_t imm
= decode_signed_value (memaddr
+ 1, info
, size
+ 1);
1613 (*info
->fprintf_func
) (info
->stream
, "#%d", imm
);
1616 operand_separator (info
);
1617 (*info
->fprintf_func
) (info
->stream
, "%s", registers
[mb
& 0x07].name
);
1620 opr_decode (memaddr
+ 1, info
);
1624 int first
= opr_n_bytes (memaddr
+ 1, info
);
1625 opr_decode (memaddr
+ 1, info
);
1626 opr_decode (memaddr
+ first
+ 1, info
);
1634 mul_n_bytes (bfd_vma memaddr
, struct disassemble_info
* info
)
1638 int status
= read_memory (memaddr
, &mb
, 1, info
);
1642 enum MUL_MODE mode
= -1;
1644 for (i
= 0; i
< sizeof (mul_table
) / sizeof (mul_table
[0]); ++i
)
1646 const struct mb
*mm
= mul_table
+ i
;
1647 if ((mb
& mm
->mask
) == mm
->value
)
1654 int size
= (mb
& 0x3) + 1;
1664 nx
+= opr_n_bytes (memaddr
+ 1, info
);
1668 int first
= opr_n_bytes (memaddr
+ nx
- 1, info
);
1670 int second
= opr_n_bytes (memaddr
+ nx
- 1, info
);
1680 /* The NXP documentation is vague about BM_RESERVED0 and BM_RESERVED1,
1681 and contains obvious typos.
1682 However the Freescale tools and experiments with the chip itself
1683 seem to indicate that they behave like BM_REG_IMM and BM_OPR_REG
1703 static const struct bm bm_table
[] = {
1704 { 0xC6, 0x04, BM_REG_IMM
},
1705 { 0x84, 0x00, BM_REG_IMM
},
1706 { 0x06, 0x06, BM_REG_IMM
},
1707 { 0xC6, 0x44, BM_RESERVED0
},
1709 { 0x8F, 0x80, BM_OPR_B
},
1710 { 0x8E, 0x82, BM_OPR_W
},
1711 { 0x8C, 0x88, BM_OPR_L
},
1713 { 0x83, 0x81, BM_OPR_REG
},
1714 { 0x87, 0x84, BM_RESERVED1
},
1718 bm_decode (bfd_vma memaddr
, struct disassemble_info
* info
)
1721 int status
= read_memory (memaddr
, &bm
, 1, info
);
1726 enum BM_MODE mode
= -1;
1727 for (i
= 0; i
< sizeof (bm_table
) / sizeof (bm_table
[0]); ++i
)
1729 const struct bm
*bme
= bm_table
+ i
;
1730 if ((bm
& bme
->mask
) == bme
->value
)
1741 operand_separator (info
);
1742 (*info
->fprintf_func
) (info
->stream
, "%s", registers
[bm
& 0x07].name
);
1745 (*info
->fprintf_func
) (info
->stream
, ".%c", 'b');
1746 opr_decode (memaddr
+ 1, info
);
1749 (*info
->fprintf_func
) (info
->stream
, ".%c", 'w');
1750 opr_decode (memaddr
+ 1, info
);
1753 (*info
->fprintf_func
) (info
->stream
, ".%c", 'l');
1754 opr_decode (memaddr
+ 1, info
);
1760 read_memory (memaddr
+ 1, &xb
, 1, info
);
1761 /* Don't emit a size suffix for register operands */
1762 if ((xb
& 0xF8) != 0xB8)
1763 (*info
->fprintf_func
) (info
->stream
, ".%c", shift_size_table
[(bm
& 0x0c) >> 2]);
1764 opr_decode (memaddr
+ 1, info
);
1770 operand_separator (info
);
1775 imm
= (bm
& 0x38) >> 3;
1776 (*info
->fprintf_func
) (info
->stream
, "#%d", imm
);
1780 imm
|= (bm
& 0x03) << 3;
1783 imm
|= (bm
& 0x01) << 3;
1786 imm
|= (bm
& 0x70) >> 4;
1787 (*info
->fprintf_func
) (info
->stream
, "#%d", imm
);
1791 (*info
->fprintf_func
) (info
->stream
, "%s", registers
[(bm
& 0x70) >> 4].name
);
1801 bm_rel_decode (bfd_vma memaddr
, struct disassemble_info
* info
)
1804 int status
= read_memory (memaddr
, &bm
, 1, info
);
1809 enum BM_MODE mode
= -1;
1810 for (i
= 0; i
< sizeof (bm_table
) / sizeof (bm_table
[0]); ++i
)
1812 const struct bm
*bme
= bm_table
+ i
;
1813 if ((bm
& bme
->mask
) == bme
->value
)
1826 (*info
->fprintf_func
) (info
->stream
, ".%c", 'b');
1829 (*info
->fprintf_func
) (info
->stream
, ".%c", 'w');
1832 (*info
->fprintf_func
) (info
->stream
, ".%c", 'l');
1838 read_memory (memaddr
+ 1, &xb
, 1, info
);
1839 /* Don't emit a size suffix for register operands */
1840 if ((xb
& 0xF8) != 0xB8)
1841 (*info
->fprintf_func
) (info
->stream
, ".%c",
1842 shift_size_table
[(bm
& 0x0C) >> 2]);
1852 operand_separator (info
);
1853 (*info
->fprintf_func
) (info
->stream
, "%s", registers
[bm
& 0x07].name
);
1858 opr_decode (memaddr
+ 1, info
);
1859 n
= 1 + opr_n_bytes (memaddr
+ 1, info
);
1863 opr_decode (memaddr
+ 1, info
);
1869 operand_separator (info
);
1873 imm
|= (bm
& 0x02) << 3;
1876 imm
|= (bm
& 0x01) << 3;
1879 imm
|= (bm
& 0x70) >> 4;
1880 (*info
->fprintf_func
) (info
->stream
, "#%d", imm
);
1883 imm
= (bm
& 0x38) >> 3;
1884 (*info
->fprintf_func
) (info
->stream
, "#%d", imm
);
1887 imm
= (bm
& 0xF8) >> 3;
1888 (*info
->fprintf_func
) (info
->stream
, "#%d", imm
);
1892 (*info
->fprintf_func
) (info
->stream
, "%s", registers
[(bm
& 0x70) >> 4].name
);
1893 n
+= opr_n_bytes (memaddr
+ 1, info
);
1897 rel_15_7 (memaddr
+ n
, info
, n
+ 1);
1901 bm_n_bytes (bfd_vma memaddr
, struct disassemble_info
* info
)
1904 int status
= read_memory (memaddr
, &bm
, 1, info
);
1909 enum BM_MODE mode
= -1;
1910 for (i
= 0; i
< sizeof (bm_table
) / sizeof (bm_table
[0]); ++i
)
1912 const struct bm
*bme
= bm_table
+ i
;
1913 if ((bm
& bme
->mask
) == bme
->value
)
1930 n
+= opr_n_bytes (memaddr
+ 1, info
);
1934 n
+= opr_n_bytes (memaddr
+ 1, info
);
1942 bm_rel_n_bytes (bfd_vma memaddr
, struct disassemble_info
* info
)
1944 int n
= 1 + bm_n_bytes (memaddr
, info
);
1947 int status
= read_memory (memaddr
+ n
- 2, &rb
, 1, info
);
1961 /* shift direction */
1992 static const struct sb sb_table
[] = {
1993 {0x30, 0x00, SB_REG_REG_N_EFF
},
1994 {0x30, 0x10, SB_REG_REG_N
},
1995 {0x34, 0x20, SB_REG_OPR_EFF
},
1996 {0x34, 0x24, SB_ROT
},
1997 {0x34, 0x30, SB_REG_OPR_OPR
},
1998 {0x34, 0x34, SB_OPR_N
},
2002 shift_n_bytes (bfd_vma memaddr
, struct disassemble_info
* info
)
2005 int status
= read_memory (memaddr
++, &sb
, 1, info
);
2010 enum SB_MODE mode
= -1;
2011 for (i
= 0; i
< sizeof (sb_table
) / sizeof (sb_table
[0]); ++i
)
2013 const struct sb
*sbe
= sb_table
+ i
;
2014 if ((sb
& sbe
->mask
) == sbe
->value
)
2020 case SB_REG_REG_N_EFF
:
2023 case SB_REG_OPR_EFF
:
2025 return 2 + opr_n_bytes (memaddr
, info
);
2027 case SB_REG_OPR_OPR
:
2029 int opr1
= opr_n_bytes (memaddr
, info
);
2031 if ((sb
& 0x30) != 0x20)
2032 opr2
= opr_n_bytes (memaddr
+ opr1
, info
);
2033 return 2 + opr1
+ opr2
;
2046 mov_imm_opr_n_bytes (bfd_vma memaddr
, struct disassemble_info
* info
)
2049 int status
= read_memory (memaddr
- 1, &byte
, 1, info
);
2053 int size
= byte
- 0x0c + 1;
2055 return size
+ opr_n_bytes (memaddr
+ size
, info
) + 1;
2059 mov_imm_opr (bfd_vma memaddr
, struct disassemble_info
* info
)
2062 int status
= read_memory (memaddr
- 1, &byte
, 1, info
);
2066 int size
= byte
- 0x0c + 1;
2067 uint32_t imm
= decode_signed_value (memaddr
, info
, size
);
2069 operand_separator (info
);
2070 (*info
->fprintf_func
) (info
->stream
, "#%d", imm
);
2071 opr_decode (memaddr
+ size
, info
);
2077 ld_18bit_decode (bfd_vma memaddr
, struct disassemble_info
* info
)
2081 int status
= read_memory (memaddr
, buffer
+ 1, 2, info
);
2086 status
= read_memory (memaddr
- 1, buffer
, 1, info
);
2090 buffer
[0] = (buffer
[0] & 0x30) >> 4;
2094 for (i
= 0; i
< size
; ++i
)
2096 imm
|= buffer
[i
] << (8 * (size
- i
- 1));
2099 operand_separator (info
);
2100 (*info
->fprintf_func
) (info
->stream
, "#%d", imm
);
2105 /* Loop Primitives */
2120 static const struct lp lp_mode
[] = {
2121 {0x08, 0x00, LP_REG
},
2122 {0x0C, 0x08, LP_XY
},
2123 {0x0C, 0x0C, LP_OPR
},
2127 static const char *lb_condition
[] =
2129 "ne", "eq", "pl", "mi", "gt", "le",
2134 loop_prim_n_bytes (bfd_vma memaddr
, struct disassemble_info
* info
)
2138 read_memory (memaddr
+ mx
++, &lb
, 1, info
);
2140 enum LP_MODE mode
= -1;
2142 for (i
= 0; i
< sizeof (lp_mode
) / sizeof (lp_mode
[0]); ++i
)
2144 const struct lp
*pb
= lp_mode
+ i
;
2145 if ((lb
& pb
->mask
) == pb
->value
)
2154 mx
+= opr_n_bytes (memaddr
+ mx
, info
) ;
2158 read_memory (memaddr
+ mx
++, &rb
, 1, info
);
2169 print_insn_exg_sex (bfd_vma memaddr
, struct disassemble_info
* info
)
2172 int status
= read_memory (memaddr
, &eb
, 1, info
);
2176 const struct reg
*first
= ®isters
[(eb
& 0xf0) >> 4];
2177 const struct reg
*second
= ®isters
[(eb
& 0xf)];
2179 if (first
->bytes
< second
->bytes
)
2180 (*info
->fprintf_func
) (info
->stream
, "sex");
2182 (*info
->fprintf_func
) (info
->stream
, "exg");
2184 operand_separator (info
);
2185 (*info
->fprintf_func
) (info
->stream
, "%s", first
->name
);
2186 operand_separator (info
);
2187 (*info
->fprintf_func
) (info
->stream
, "%s", second
->name
);
2194 print_insn_loop_primitive (bfd_vma memaddr
, struct disassemble_info
* info
)
2198 int status
= read_memory (memaddr
, &lb
, 1, info
);
2202 mnemonic
[x
++] = (lb
& 0x80) ? 'd' : 't';
2203 mnemonic
[x
++] = 'b';
2204 stpcpy (mnemonic
+ x
, lb_condition
[(lb
& 0x70) >> 4]);
2207 const char *reg_dxy
= NULL
;
2208 enum LP_MODE mode
= -1;
2210 for (i
= 0; i
< sizeof (lp_mode
) / sizeof (lp_mode
[0]); ++i
)
2212 const struct lp
*pb
= lp_mode
+ i
;
2213 if ((lb
& pb
->mask
) == pb
->value
)
2223 reg_dxy
= registers
[lb
& 0x07].name
;
2226 reg_dxy
= (lb
& 0x1) ? "y" : "x";
2229 mnemonic
[x
++] = '.';
2230 mnemonic
[x
++] = shift_size_table
[lb
& 0x03];
2231 offs
+= opr_n_bytes (memaddr
+ 1, info
);
2235 mnemonic
[x
++] = '\0';
2237 (*info
->fprintf_func
) (info
->stream
, "%s", mnemonic
);
2240 opr_decode (memaddr
+ 1, info
);
2243 operand_separator (info
);
2244 (*info
->fprintf_func
) (info
->stream
, "%s", reg_dxy
);
2247 rel_15_7 (memaddr
+ offs
, info
, offs
+ 1);
2254 print_insn_shift (bfd_vma memaddr
, struct disassemble_info
* info
, uint8_t byte
)
2258 int status
= read_memory (memaddr
, &sb
, 1, info
);
2262 enum SB_DIR dir
= (sb
& 0x40) ? SB_LEFT
: SB_RIGHT
;
2263 enum SB_TYPE type
= (sb
& 0x80) ? SB_ARITHMETIC
: SB_LOGICAL
;
2264 enum SB_MODE mode
= -1;
2265 for (i
= 0; i
< sizeof (sb_table
) / sizeof (sb_table
[0]); ++i
)
2267 const struct sb
*sbe
= sb_table
+ i
;
2268 if ((sb
& sbe
->mask
) == sbe
->value
)
2276 mnemonic
[x
++] = 'r';
2277 mnemonic
[x
++] = 'o';
2281 mnemonic
[x
++] = (type
== SB_LOGICAL
) ? 'l' : 'a';
2282 mnemonic
[x
++] = 's';
2285 mnemonic
[x
++] = (dir
== SB_LEFT
) ? 'l' : 'r';
2289 case SB_REG_OPR_EFF
:
2291 case SB_REG_OPR_OPR
:
2292 mnemonic
[x
++] = '.';
2293 mnemonic
[x
++] = shift_size_table
[sb
& 0x03];
2298 read_memory (memaddr
+ 1, &xb
, 1, info
);
2299 /* The size suffix is not printed if the OPR operand refers
2300 directly to a register, because the size is implied by the
2301 size of that register. */
2302 if ((xb
& 0xF8) != 0xB8)
2304 mnemonic
[x
++] = '.';
2305 mnemonic
[x
++] = shift_size_table
[sb
& 0x03];
2313 mnemonic
[x
++] = '\0';
2315 (*info
->fprintf_func
) (info
->stream
, "%s", mnemonic
);
2317 /* Destination register */
2320 case SB_REG_REG_N_EFF
:
2322 case SB_REG_OPR_EFF
:
2323 case SB_REG_OPR_OPR
:
2324 operand_separator (info
);
2325 (*info
->fprintf_func
) (info
->stream
, "%s", registers
[byte
& 0x7].name
);
2329 opr_decode (memaddr
+ 1, info
);
2336 /* Source register */
2339 case SB_REG_REG_N_EFF
:
2341 operand_separator (info
);
2342 (*info
->fprintf_func
) (info
->stream
, "%s", registers
[sb
& 0x7].name
);
2345 case SB_REG_OPR_OPR
:
2346 opr_decode (memaddr
+ 1, info
);
2356 case SB_REG_OPR_EFF
:
2358 opr_decode (memaddr
+ 1, info
);
2364 operand_separator (info
);
2368 read_memory (memaddr
+ 1, &xb
, 1, info
);
2369 int shift
= ((sb
& 0x08) >> 3) | ((xb
& 0x0f) << 1);
2370 (*info
->fprintf_func
) (info
->stream
, "#%d", shift
);
2374 (*info
->fprintf_func
) (info
->stream
, "%s:%d", __FILE__
, __LINE__
);
2379 opr_decode (memaddr
+ 1, info
);
2382 case SB_REG_OPR_OPR
:
2385 int n
= opr_n_bytes (memaddr
+ 1, info
);
2386 read_memory (memaddr
+ 1 + n
, &xb
, 1, info
);
2388 if ((xb
& 0xF0) == 0x70)
2390 int imm
= xb
& 0x0F;
2392 imm
|= (sb
& 0x08) >> 3;
2393 operand_separator (info
);
2394 (*info
->fprintf_func
) (info
->stream
, "#%d", imm
);
2398 opr_decode (memaddr
+ 1 + n
, info
);
2408 case SB_REG_REG_N_EFF
:
2409 case SB_REG_OPR_EFF
:
2411 operand_separator (info
);
2412 (*info
->fprintf_func
) (info
->stream
, "#%d",
2413 (sb
& 0x08) ? 2 : 1);
2424 print_insn_s12z (bfd_vma memaddr
, struct disassemble_info
* info
)
2427 int status
= read_memory (memaddr
++, &byte
, 1, info
);
2431 const struct opcode
*opc2
= NULL
;
2432 const struct opcode
*opc
= page1
+ byte
;
2435 (*info
->fprintf_func
) (info
->stream
, "%s", opc
->mnemonic
);
2439 /* The special cases ... */
2445 read_memory (memaddr
++, &byte2
, 1, info
);
2446 opc2
= page2
+ byte2
;
2449 (*info
->fprintf_func
) (info
->stream
, "%s", opc2
->mnemonic
);
2453 opc2
->operands (memaddr
, info
);
2456 if (opc2
->operands2
)
2458 opc2
->operands2 (memaddr
, info
);
2461 else if (byte2
>= 0x08 && byte2
<= 0x1F)
2464 read_memory (memaddr
, &bb
, 1, info
);
2466 (*info
->fprintf_func
) (info
->stream
, "bfins");
2468 (*info
->fprintf_func
) (info
->stream
, "bfext");
2470 enum BB_MODE mode
= -1;
2472 const struct opr_bb
*bbs
= 0;
2473 for (i
= 0; i
< sizeof (bb_modes
) / sizeof (bb_modes
[0]); ++i
)
2476 if ((bb
& bbs
->mask
) == bbs
->value
)
2485 case BB_REG_OPR_REG
:
2486 case BB_REG_OPR_IMM
:
2487 case BB_OPR_REG_REG
:
2488 case BB_OPR_REG_IMM
:
2490 int size
= (bb
>> 2) & 0x03;
2491 (*info
->fprintf_func
) (info
->stream
, ".%c",
2492 shift_size_table
[size
]);
2499 int reg1
= byte2
& 0x07;
2503 case BB_REG_REG_REG
:
2504 case BB_REG_REG_IMM
:
2505 case BB_REG_OPR_REG
:
2506 case BB_REG_OPR_IMM
:
2507 operand_separator (info
);
2508 (*info
->fprintf_func
) (info
->stream
, "%s",
2509 registers
[reg1
].name
);
2511 case BB_OPR_REG_REG
:
2512 opr_decode (memaddr
+ 1, info
);
2514 case BB_OPR_REG_IMM
:
2515 opr_decode (memaddr
+ 2, info
);
2519 /* Second operand */
2522 case BB_REG_REG_REG
:
2523 case BB_REG_REG_IMM
:
2525 int reg_src
= (bb
>> 2) & 0x07;
2526 operand_separator (info
);
2527 (*info
->fprintf_func
) (info
->stream
, "%s",
2528 registers
[reg_src
].name
);
2531 case BB_OPR_REG_REG
:
2532 case BB_OPR_REG_IMM
:
2534 int reg_src
= (byte2
& 0x07);
2535 operand_separator (info
);
2536 (*info
->fprintf_func
) (info
->stream
, "%s",
2537 registers
[reg_src
].name
);
2540 case BB_REG_OPR_REG
:
2541 opr_decode (memaddr
+ 1, info
);
2543 case BB_REG_OPR_IMM
:
2544 opr_decode (memaddr
+ 2, info
);
2549 operand_separator (info
);
2552 case BB_REG_REG_REG
:
2553 case BB_OPR_REG_REG
:
2554 case BB_REG_OPR_REG
:
2556 int reg_parm
= bb
& 0x03;
2557 (*info
->fprintf_func
) (info
->stream
, "%s",
2558 registers
[reg_parm
].name
);
2561 case BB_REG_REG_IMM
:
2562 case BB_OPR_REG_IMM
:
2563 case BB_REG_OPR_IMM
:
2566 read_memory (memaddr
+ 1, &i1
, 1, info
);
2567 int offset
= i1
& 0x1f;
2568 int width
= bb
& 0x03;
2571 (*info
->fprintf_func
) (info
->stream
, "#%d:%d", width
, offset
);
2578 case 0xae: /* EXG / SEX */
2579 status
= print_insn_exg_sex (memaddr
, info
);
2581 case 0x0b: /* Loop Primitives TBcc and DBcc */
2582 status
= print_insn_loop_primitive (memaddr
, info
);
2584 case 0x10: /* shift */
2585 case 0x11: /* shift */
2586 case 0x12: /* shift */
2587 case 0x13: /* shift */
2588 case 0x14: /* shift */
2589 case 0x15: /* shift */
2590 case 0x16: /* shift */
2591 case 0x17: /* shift */
2592 status
= print_insn_shift (memaddr
, info
, byte
);
2594 case 0x04: /* psh / pul */
2596 read_memory (memaddr
, &byte
, 1, info
);
2597 (*info
->fprintf_func
) (info
->stream
, (byte
& 0x80) ? "pul" : "psh");
2601 if ((byte
& 0x3F) == 0)
2603 operand_separator (info
);
2604 (*info
->fprintf_func
) (info
->stream
, "%s", "ALL16b");
2607 for (bit
= 5; bit
>= 0; --bit
)
2609 if (byte
& (0x1 << bit
))
2611 operand_separator (info
);
2612 (*info
->fprintf_func
) (info
->stream
, "%s", oprregs2
[bit
]);
2618 if ((byte
& 0x3F) == 0)
2620 operand_separator (info
);
2621 (*info
->fprintf_func
) (info
->stream
, "%s", "ALL");
2624 for (bit
= 5; bit
>= 0; --bit
)
2626 if (byte
& (0x1 << bit
))
2628 operand_separator (info
);
2629 (*info
->fprintf_func
) (info
->stream
, "%s", oprregs1
[bit
]);
2636 operand_separator (info
);
2637 (*info
->fprintf_func
) (info
->stream
, "???");
2646 opc
->operands (memaddr
, info
);
2651 opc
->operands2 (memaddr
, info
);
2657 /* Opcodes in page2 have an additional byte */
2661 if (opc2
&& opc2
->insn_bytes
== 0)
2664 if (!opc2
&& opc
->insn_bytes
== 0)
2668 n
+= opc2
->insn_bytes (memaddr
, info
);
2670 n
+= opc
->insn_bytes (memaddr
, info
);