1 /* Disassemble MN10300 instructions.
2 Copyright (C) 1996, 1997 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 int));
29 print_insn_mn10300 (memaddr, info)
31 struct disassemble_info *info;
38 /* First figure out how big the opcode is. */
39 status = (*info->read_memory_func) (memaddr, buffer, 1, info);
42 (*info->memory_error_func) (status, memaddr, info);
45 insn = *(unsigned char *) buffer;
47 /* These are one byte insns. */
48 if ((insn & 0xf3) == 0x00
49 || (insn & 0xf0) == 0x10
50 || (insn & 0xfc) == 0x3c
51 || (insn & 0xf3) == 0x41
52 || (insn & 0xf3) == 0x40
53 || (insn & 0xfc) == 0x50
54 || (insn & 0xfc) == 0x54
55 || (insn & 0xf0) == 0x60
56 || (insn & 0xf0) == 0x70
57 || ((insn & 0xf0) == 0x80
58 && (insn & 0x0c) >> 2 != (insn & 0x03))
59 || ((insn & 0xf0) == 0x90
60 && (insn & 0x0c) >> 2 != (insn & 0x03))
61 || ((insn & 0xf0) == 0xa0
62 && (insn & 0x0c) >> 2 != (insn & 0x03))
63 || ((insn & 0xf0) == 0xb0
64 && (insn & 0x0c) >> 2 != (insn & 0x03))
65 || (insn & 0xff) == 0xcb
66 || (insn & 0xfc) == 0xd0
67 || (insn & 0xfc) == 0xd4
68 || (insn & 0xfc) == 0xd8
69 || (insn & 0xf0) == 0xe0)
74 /* These are two byte insns. */
75 else if ((insn & 0xf0) == 0x80
76 || (insn & 0xf0) == 0x90
77 || (insn & 0xf0) == 0xa0
78 || (insn & 0xf0) == 0xb0
79 || (insn & 0xfc) == 0x20
80 || (insn & 0xfc) == 0x28
81 || (insn & 0xf3) == 0x43
82 || (insn & 0xf3) == 0x42
83 || (insn & 0xfc) == 0x58
84 || (insn & 0xfc) == 0x5c
85 || ((insn & 0xf0) == 0xc0
86 && (insn & 0xff) != 0xcb
87 && (insn & 0xff) != 0xcc
88 && (insn & 0xff) != 0xcd)
89 || (insn & 0xff) == 0xf0
90 || (insn & 0xff) == 0xf1
91 || (insn & 0xff) == 0xf2
92 || (insn & 0xff) == 0xf3
93 || (insn & 0xff) == 0xf4
94 || (insn & 0xff) == 0xf5
95 || (insn & 0xff) == 0xf6)
97 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
100 (*info->memory_error_func) (status, memaddr, info);
103 insn = bfd_getb16 (buffer);
107 /* These are three byte insns. */
108 else if ((insn & 0xff) == 0xf8
109 || (insn & 0xff) == 0xcc
110 || (insn & 0xff) == 0xf9
111 || (insn & 0xf3) == 0x01
112 || (insn & 0xf3) == 0x02
113 || (insn & 0xf3) == 0x03
114 || (insn & 0xfc) == 0x24
115 || (insn & 0xfc) == 0x2c
116 || (insn & 0xfc) == 0x30
117 || (insn & 0xfc) == 0x34
118 || (insn & 0xfc) == 0x38
119 || (insn & 0xff) == 0xde
120 || (insn & 0xff) == 0xdf
121 || (insn & 0xff) == 0xcc)
123 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
126 (*info->memory_error_func) (status, memaddr, info);
129 insn = bfd_getb16 (buffer);
131 status = (*info->read_memory_func) (memaddr + 2, buffer, 1, info);
134 (*info->memory_error_func) (status, memaddr, info);
137 insn |= *(unsigned char *)buffer;
141 /* These are four byte insns. */
142 else if ((insn & 0xff) == 0xfa
143 || (insn & 0xff) == 0xfb)
145 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
148 (*info->memory_error_func) (status, memaddr, info);
151 insn = bfd_getb32 (buffer);
155 /* These are five byte insns. */
156 else if ((insn & 0xff) == 0xcd
157 || (insn & 0xff) == 0xdc)
159 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
162 (*info->memory_error_func) (status, memaddr, info);
165 insn = bfd_getb32 (buffer);
169 /* These are six byte insns. */
170 else if ((insn & 0xff) == 0xfd
171 || (insn & 0xff) == 0xfc)
173 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
176 (*info->memory_error_func) (status, memaddr, info);
180 insn = bfd_getb32 (buffer);
184 /* Else its a seven byte insns (in theory). */
187 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
190 (*info->memory_error_func) (status, memaddr, info);
194 insn = bfd_getb32 (buffer);
198 disassemble (memaddr, info, insn, consume);
204 disassemble (memaddr, info, insn, size)
206 struct disassemble_info *info;
210 struct mn10300_opcode *op = (struct mn10300_opcode *)mn10300_opcodes;
211 const struct mn10300_operand *operand;
213 unsigned long extension = 0;
214 int status, match = 0;
216 /* Find the opcode. */
219 int mysize, extra_shift;
221 if (op->format == FMT_S0)
223 else if (op->format == FMT_S1
224 || op->format == FMT_D0)
226 else if (op->format == FMT_S2
227 || op->format == FMT_D1)
229 else if (op->format == FMT_S4)
231 else if (op->format == FMT_D2)
233 else if (op->format == FMT_D4)
238 if ((op->mask & insn) == op->opcode
241 const unsigned char *opindex_ptr;
242 unsigned int nocomma;
245 if (op->format == FMT_D1 || op->format == FMT_S1)
247 else if (op->format == FMT_D2 || op->format == FMT_D4
248 || op->format == FMT_S2 || op->format == FMT_S4
249 || op->format == FMT_S6 || op->format == FMT_D5)
254 if (size == 1 || size == 2)
259 && (op->format == FMT_D1
260 || op->opcode == 0xdf0000
261 || op->opcode == 0xde0000))
268 status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
271 (*info->memory_error_func) (status, memaddr, info);
275 insn |= bfd_getl16 (buffer);
279 && (op->opcode == 0xfaf80000
280 || op->opcode == 0xfaf00000
281 || op->opcode == 0xfaf40000))
288 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
291 (*info->memory_error_func) (status, memaddr, info);
295 insn |= bfd_getl16 (buffer);
298 else if (size == 5 && op->opcode == 0xdc000000)
300 unsigned long temp = 0;
301 status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
304 (*info->memory_error_func) (status, memaddr, info);
307 temp |= bfd_getl32 (buffer);
310 insn |= (temp & 0xffffff00) >> 8;
311 extension = temp & 0xff;
315 unsigned long temp = 0;
316 status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
319 (*info->memory_error_func) (status, memaddr, info);
322 temp |= bfd_getl16 (buffer);
327 status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
330 (*info->memory_error_func) (status, memaddr, info);
333 extension = *(unsigned char *)buffer;
337 unsigned long temp = 0;
338 status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
341 (*info->memory_error_func) (status, memaddr, info);
344 temp |= bfd_getl32 (buffer);
347 insn |= (temp >> 16) & 0xffff;
348 extension = temp & 0xffff;
350 else if (size == 7 && op->opcode == 0xdd000000)
352 unsigned long temp = 0;
353 status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
356 (*info->memory_error_func) (status, memaddr, info);
359 temp |= bfd_getl32 (buffer);
362 insn |= (temp >> 8) & 0xffffff;
363 extension = (temp & 0xff) << 16;
365 status = (*info->read_memory_func) (memaddr + 5, buffer, 2, info);
368 (*info->memory_error_func) (status, memaddr, info);
371 extension |= bfd_getb16 (buffer);
375 unsigned long temp = 0;
376 status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
379 (*info->memory_error_func) (status, memaddr, info);
382 temp |= bfd_getl32 (buffer);
385 insn |= (temp >> 16) & 0xffff;
386 extension = (temp & 0xffff) << 8;
388 status = (*info->read_memory_func) (memaddr + 6, buffer, 1, info);
391 (*info->memory_error_func) (status, memaddr, info);
394 extension |= *(unsigned char *)buffer;
398 (*info->fprintf_func) (info->stream, "%s\t", op->name);
400 /* Now print the operands. */
401 for (opindex_ptr = op->operands, nocomma = 1;
407 operand = &mn10300_operands[*opindex_ptr];
409 if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
412 value = insn & ((1 << operand->bits) - 1);
413 value <<= (32 - operand->bits);
414 temp = extension >> operand->shift;
415 temp &= ((1 << (32 - operand->bits)) - 1);
418 else if ((operand->flags & MN10300_OPERAND_EXTENDED) != 0)
420 value = ((extension >> (operand->shift))
421 & ((1 << operand->bits) - 1));
425 value = ((insn >> (operand->shift))
426 & ((1 << operand->bits) - 1));
429 if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
430 value = ((long)(value << (32 - operand->bits))
431 >> (32 - operand->bits));
435 || ((operand->flags & MN10300_OPERAND_PAREN) == 0)))
436 (*info->fprintf_func) (info->stream, ",");
440 if ((operand->flags & MN10300_OPERAND_DREG) != 0)
442 value = ((insn >> (operand->shift + extra_shift))
443 & ((1 << operand->bits) - 1));
444 (*info->fprintf_func) (info->stream, "d%d", value);
447 else if ((operand->flags & MN10300_OPERAND_AREG) != 0)
449 value = ((insn >> (operand->shift + extra_shift))
450 & ((1 << operand->bits) - 1));
451 (*info->fprintf_func) (info->stream, "a%d", value);
454 else if ((operand->flags & MN10300_OPERAND_SP) != 0)
455 (*info->fprintf_func) (info->stream, "sp");
457 else if ((operand->flags & MN10300_OPERAND_PSW) != 0)
458 (*info->fprintf_func) (info->stream, "psw");
460 else if ((operand->flags & MN10300_OPERAND_MDR) != 0)
461 (*info->fprintf_func) (info->stream, "mdr");
463 else if ((operand->flags & MN10300_OPERAND_PAREN) != 0)
466 (*info->fprintf_func) (info->stream, ")");
469 (*info->fprintf_func) (info->stream, "(");
475 else if ((operand->flags & MN10300_OPERAND_PCREL) != 0)
476 (*info->print_address_func) (value + memaddr, info);
478 else if ((operand->flags & MN10300_OPERAND_MEMADDR) != 0)
479 (*info->print_address_func) (value, info);
481 else if ((operand->flags & MN10300_OPERAND_REG_LIST) != 0)
485 (*info->fprintf_func) (info->stream, "[");
488 (*info->fprintf_func) (info->stream, "d2");
495 (*info->fprintf_func) (info->stream, ",");
496 (*info->fprintf_func) (info->stream, "d3");
503 (*info->fprintf_func) (info->stream, ",");
504 (*info->fprintf_func) (info->stream, "a2");
511 (*info->fprintf_func) (info->stream, ",");
512 (*info->fprintf_func) (info->stream, "a3");
519 (*info->fprintf_func) (info->stream, ",");
520 (*info->fprintf_func) (info->stream, "other");
523 (*info->fprintf_func) (info->stream, "]");
527 (*info->fprintf_func) (info->stream, "%d", value);
537 (*info->fprintf_func) (info->stream, "unknown\t0x%04x", insn);