1 /* Disassemble MN10300 instructions.
2 Copyright (C) 1996 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"
25 static void disassemble
PARAMS ((bfd_vma
, struct disassemble_info
*,
26 unsigned long insn
, unsigned long,
29 static const char *const mn10300_reg_names
[] =
30 { "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3", };
33 print_insn_mn10300 (memaddr
, info
)
35 struct disassemble_info
*info
;
40 unsigned long extension
;
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 XXX imm8 versions of mov, cmp. */
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)
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
);
114 /* These are three byte insns. */
115 else if ((insn
& 0xff) == 0xf8
116 || (insn
& 0xff) == 0xcc
117 || (insn
& 0xff) == 0xf9
118 || (insn
& 0xf3) == 0x01
119 || (insn
& 0xf3) == 0x02
120 || (insn
& 0xf3) == 0x03
121 || (insn
& 0xfc) == 0x24
122 || (insn
& 0xfc) == 0x2c
123 || (insn
& 0xfc) == 0x30
124 || (insn
& 0xfc) == 0x34
125 || (insn
& 0xfc) == 0x38
126 || (insn
& 0xff) == 0xde
127 || (insn
& 0xff) == 0xdf
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 insn
|= *(unsigned char *)buffer
+ 2;
143 /* These are four byte insns. */
144 else if ((insn
& 0xff) == 0xfa
145 || (insn
& 0xff) == 0xfb)
147 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
150 (*info
->memory_error_func
) (status
, memaddr
, info
);
153 insn
= bfd_getb32 (buffer
);
158 /* These are five byte insns. */
159 else if ((insn
& 0xff) == 0xcd
160 || (insn
& 0xff) == 0xdc)
162 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
165 (*info
->memory_error_func
) (status
, memaddr
, info
);
168 insn
= bfd_getb32 (buffer
);
170 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 1, info
);
173 (*info
->memory_error_func
) (status
, memaddr
, info
);
176 extension
= *(unsigned char *) buffer
+ 4;
180 /* These are six byte insns. */
181 else if ((insn
& 0xff) == 0xfd
182 || (insn
& 0xff) == 0xfc)
184 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
187 (*info
->memory_error_func
) (status
, memaddr
, info
);
191 insn
= bfd_getb32 (buffer
);
192 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
195 (*info
->memory_error_func
) (status
, memaddr
, info
);
198 extension
= bfd_getb16 (buffer
+ 4);
202 /* Else its a seven byte insns (in theory). */
205 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
208 (*info
->memory_error_func
) (status
, memaddr
, info
);
212 insn
= bfd_getb32 (buffer
);
213 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
216 (*info
->memory_error_func
) (status
, memaddr
, info
);
219 extension
= bfd_getb16 (buffer
);
221 extension
|= *(unsigned char *)buffer
+ 2;
225 disassemble (memaddr
, info
, insn
, extension
, consume
);
231 disassemble (memaddr
, info
, insn
, extension
, size
)
233 struct disassemble_info
*info
;
235 unsigned long extension
;
238 struct mn10300_opcode
*op
= (struct mn10300_opcode
*)mn10300_opcodes
;
239 const struct mn10300_operand
*operand
;
242 /* Find the opcode. */
247 if (op
->format
== FMT_S0
)
249 else if (op
->format
== FMT_S1
250 || op
->format
== FMT_D0
)
252 else if (op
->format
== FMT_S2
253 || op
->format
== FMT_D1
)
255 else if (op
->format
== FMT_S4
)
257 else if (op
->format
== FMT_D2
)
259 else if (op
->format
== FMT_D4
)
264 if ((op
->mask
& insn
) == op
->opcode
267 const unsigned char *opindex_ptr
;
268 unsigned int opnum
, memop
;
271 (*info
->fprintf_func
) (info
->stream
, "%s\t", op
->name
);
273 /* Now print the operands. */
274 for (opindex_ptr
= op
->operands
, opnum
= 1;
276 opindex_ptr
++, opnum
++)
280 operand
= &mn10300_operands
[*opindex_ptr
];
282 value
= (insn
>> operand
->shift
) & ((1 << operand
->bits
) - 1);
284 if ((operand
->flags
& MN10300_OPERAND_SIGNED
) != 0)
285 value
= ((long)(value
<< (32 - operand
->bits
))
286 >> (32 - operand
->bits
));
296 (*info
->fprintf_func
) (info
->stream
, "unknown\t0x%04x", insn
);
This page took 0.053239 seconds and 5 git commands to generate.