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
);
This page took 0.071237 seconds and 4 git commands to generate.