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,
30 print_insn_mn10300 (memaddr
, info
)
32 struct disassemble_info
*info
;
37 unsigned long extension
;
40 /* First figure out how big the opcode is. */
41 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 1, info
);
44 (*info
->memory_error_func
) (status
, memaddr
, info
);
47 insn
= *(unsigned char *) buffer
;
49 /* These are one byte insns. */
50 if ((insn
& 0xf3) == 0x00
51 || (insn
& 0xf0) == 0x10
52 || (insn
& 0xfc) == 0x3c
53 || (insn
& 0xf3) == 0x41
54 || (insn
& 0xf3) == 0x40
55 || (insn
& 0xfc) == 0x50
56 || (insn
& 0xfc) == 0x54
57 || (insn
& 0xf0) == 0x60
58 || (insn
& 0xf0) == 0x70
59 || ((insn
& 0xf0) == 0x80
60 && (insn
& 0x0c) >> 2 != (insn
& 0x03))
61 || ((insn
& 0xf0) == 0x90
62 && (insn
& 0x0c) >> 2 != (insn
& 0x03))
63 || ((insn
& 0xf0) == 0xa0
64 && (insn
& 0x0c) >> 2 != (insn
& 0x03))
65 || ((insn
& 0xf0) == 0xb0
66 && (insn
& 0x0c) >> 2 != (insn
& 0x03))
67 || (insn
& 0xff) == 0xcb
68 || (insn
& 0xfc) == 0xd0
69 || (insn
& 0xfc) == 0xd4
70 || (insn
& 0xfc) == 0xd8
71 || (insn
& 0xf0) == 0xe0)
77 /* These are two byte insns. */
78 else if ((insn
& 0xf0) == 0x80
79 || (insn
& 0xf0) == 0x90
80 || (insn
& 0xf0) == 0xa0
81 || (insn
& 0xf0) == 0xb0
82 || (insn
& 0xfc) == 0x20
83 || (insn
& 0xfc) == 0x28
84 || (insn
& 0xf3) == 0x43
85 || (insn
& 0xf3) == 0x42
86 || (insn
& 0xfc) == 0x58
87 || (insn
& 0xfc) == 0x5c
88 || ((insn
& 0xf0) == 0xc0
89 && (insn
& 0xff) != 0xcb
90 && (insn
& 0xff) != 0xcc
91 && (insn
& 0xff) != 0xcd)
92 || (insn
& 0xff) == 0xf0
93 || (insn
& 0xff) == 0xf1
94 || (insn
& 0xff) == 0xf2
95 || (insn
& 0xff) == 0xf3
96 || (insn
& 0xff) == 0xf4
97 || (insn
& 0xff) == 0xf5
98 || (insn
& 0xff) == 0xf6)
100 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
103 (*info
->memory_error_func
) (status
, memaddr
, info
);
106 insn
= bfd_getb16 (buffer
);
111 /* These are three byte insns. */
112 else if ((insn
& 0xff) == 0xf8
113 || (insn
& 0xff) == 0xcc
114 || (insn
& 0xff) == 0xf9
115 || (insn
& 0xf3) == 0x01
116 || (insn
& 0xf3) == 0x02
117 || (insn
& 0xf3) == 0x03
118 || (insn
& 0xfc) == 0x24
119 || (insn
& 0xfc) == 0x2c
120 || (insn
& 0xfc) == 0x30
121 || (insn
& 0xfc) == 0x34
122 || (insn
& 0xfc) == 0x38
123 || (insn
& 0xff) == 0xde
124 || (insn
& 0xff) == 0xdf
125 || (insn
& 0xff) == 0xcc)
127 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
130 (*info
->memory_error_func
) (status
, memaddr
, info
);
133 insn
= bfd_getb16 (buffer
);
135 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 1, info
);
138 (*info
->memory_error_func
) (status
, memaddr
, info
);
141 insn
|= *(unsigned char *)buffer
;
146 /* These are four byte insns. */
147 else if ((insn
& 0xff) == 0xfa
148 || (insn
& 0xff) == 0xfb)
150 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
153 (*info
->memory_error_func
) (status
, memaddr
, info
);
156 insn
= bfd_getb32 (buffer
);
161 /* These are five byte insns. */
162 else if ((insn
& 0xff) == 0xcd
163 || (insn
& 0xff) == 0xdc)
165 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
168 (*info
->memory_error_func
) (status
, memaddr
, info
);
171 insn
= bfd_getb32 (buffer
);
173 status
= (*info
->read_memory_func
) (memaddr
+ 4, buffer
, 1, info
);
176 (*info
->memory_error_func
) (status
, memaddr
+ 4, info
);
179 extension
= *(unsigned char *) buffer
;
183 /* These are six byte insns. */
184 else if ((insn
& 0xff) == 0xfd
185 || (insn
& 0xff) == 0xfc)
187 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
190 (*info
->memory_error_func
) (status
, memaddr
, info
);
194 insn
= bfd_getb32 (buffer
);
195 status
= (*info
->read_memory_func
) (memaddr
+ 4, buffer
, 2, info
);
198 (*info
->memory_error_func
) (status
, memaddr
+ 4, info
);
201 extension
= bfd_getb16 (buffer
);
205 /* Else its a seven byte insns (in theory). */
208 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 4, info
);
211 (*info
->memory_error_func
) (status
, memaddr
, info
);
215 insn
= bfd_getb32 (buffer
);
216 status
= (*info
->read_memory_func
) (memaddr
+ 4, buffer
, 2, info
);
219 (*info
->memory_error_func
) (status
, memaddr
+ 4, info
);
222 extension
= bfd_getb16 (buffer
);
224 status
= (*info
->read_memory_func
) (memaddr
+ 6, buffer
, 1, info
);
227 (*info
->memory_error_func
) (status
, memaddr
+ 6, info
);
230 extension
|= *(unsigned char *)buffer
;
234 disassemble (memaddr
, info
, insn
, extension
, consume
);
240 disassemble (memaddr
, info
, insn
, extension
, size
)
242 struct disassemble_info
*info
;
244 unsigned long extension
;
247 struct mn10300_opcode
*op
= (struct mn10300_opcode
*)mn10300_opcodes
;
248 const struct mn10300_operand
*operand
;
251 /* Find the opcode. */
254 int mysize
, extra_shift
;
256 if (op
->format
== FMT_S0
)
258 else if (op
->format
== FMT_S1
259 || op
->format
== FMT_D0
)
261 else if (op
->format
== FMT_S2
262 || op
->format
== FMT_D1
)
264 else if (op
->format
== FMT_S4
)
266 else if (op
->format
== FMT_D2
)
268 else if (op
->format
== FMT_D4
)
273 if (op
->format
== FMT_D1
|| op
->format
== FMT_S1
)
275 else if (op
->format
== FMT_D2
|| op
->format
== FMT_D4
276 || op
->format
== FMT_S2
|| op
->format
== FMT_S4
277 || op
->format
== FMT_S6
|| op
->format
== FMT_D5
)
282 if ((op
->mask
& insn
) == op
->opcode
285 const unsigned char *opindex_ptr
;
286 unsigned int nocomma
, memop
;
290 (*info
->fprintf_func
) (info
->stream
, "%s\t", op
->name
);
292 /* Now print the operands. */
293 for (opindex_ptr
= op
->operands
, nocomma
= 1;
299 operand
= &mn10300_operands
[*opindex_ptr
];
301 if ((operand
->flags
& MN10300_OPERAND_SPLIT
) != 0)
304 value
= insn
& ((1 << operand
->bits
) - 1);
305 value
<<= (32 - operand
->bits
);
306 temp
= extension
>> operand
->shift
;
307 temp
&= ((1 << 32 - operand
->bits
) - 1);
310 else if ((operand
->flags
& MN10300_OPERAND_EXTENDED
) != 0)
312 value
= ((extension
>> (operand
->shift
))
313 & ((1 << operand
->bits
) - 1));
317 value
= ((insn
>> (operand
->shift
))
318 & ((1 << operand
->bits
) - 1));
321 if ((operand
->flags
& MN10300_OPERAND_SIGNED
) != 0)
322 value
= ((long)(value
<< (32 - operand
->bits
))
323 >> (32 - operand
->bits
));
327 || ((operand
->flags
& MN10300_OPERAND_PAREN
) == 0)))
328 (*info
->fprintf_func
) (info
->stream
, ",");
332 if ((operand
->flags
& MN10300_OPERAND_DREG
) != 0)
334 value
= ((insn
>> (operand
->shift
+ extra_shift
))
335 & ((1 << operand
->bits
) - 1));
336 (*info
->fprintf_func
) (info
->stream
, "$d%d", value
);
339 else if ((operand
->flags
& MN10300_OPERAND_AREG
) != 0)
341 value
= ((insn
>> (operand
->shift
+ extra_shift
))
342 & ((1 << operand
->bits
) - 1));
343 (*info
->fprintf_func
) (info
->stream
, "$a%d", value
);
346 else if ((operand
->flags
& MN10300_OPERAND_SP
) != 0)
347 (*info
->fprintf_func
) (info
->stream
, "$sp");
349 else if ((operand
->flags
& MN10300_OPERAND_PSW
) != 0)
350 (*info
->fprintf_func
) (info
->stream
, "$psw");
352 else if ((operand
->flags
& MN10300_OPERAND_MDR
) != 0)
353 (*info
->fprintf_func
) (info
->stream
, "$mdr");
355 else if ((operand
->flags
& MN10300_OPERAND_PAREN
) != 0)
358 (*info
->fprintf_func
) (info
->stream
, ")");
361 (*info
->fprintf_func
) (info
->stream
, "(");
367 else if ((operand
->flags
& MN10300_OPERAND_PCREL
) != 0)
368 (*info
->print_address_func
) (value
+ memaddr
, info
);
370 else if ((operand
->flags
& MN10300_OPERAND_MEMADDR
) != 0)
371 (*info
->print_address_func
) (value
, info
);
373 else if ((operand
->flags
& MN10300_OPERAND_REG_LIST
) != 0)
377 (*info
->fprintf_func
) (info
->stream
, "[");
380 (*info
->fprintf_func
) (info
->stream
, "%d2");
387 (*info
->fprintf_func
) (info
->stream
, ",");
388 (*info
->fprintf_func
) (info
->stream
, "%d3");
395 (*info
->fprintf_func
) (info
->stream
, ",");
396 (*info
->fprintf_func
) (info
->stream
, "%a2");
403 (*info
->fprintf_func
) (info
->stream
, ",");
404 (*info
->fprintf_func
) (info
->stream
, "%a3");
411 (*info
->fprintf_func
) (info
->stream
, ",");
412 (*info
->fprintf_func
) (info
->stream
, "%other");
415 (*info
->fprintf_func
) (info
->stream
, "]");
419 (*info
->fprintf_func
) (info
->stream
, "%d", value
);
429 (*info
->fprintf_func
) (info
->stream
, "unknown\t0x%04x", insn
);