1 /* Disassemble MN10200 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/mn10200.h"
25 static void disassemble
PARAMS ((bfd_vma
, struct disassemble_info
*,
26 unsigned long insn
, unsigned long,
30 print_insn_mn10200 (memaddr
, info
)
32 struct disassemble_info
*info
;
36 unsigned long insn
, extension
;
39 /* First figure out how big the opcode is. */
40 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 1, info
);
43 (*info
->memory_error_func
) (status
, memaddr
, info
);
46 insn
= *(unsigned char *) buffer
;
48 /* These are one byte insns. */
49 if ((insn
& 0xf0) == 0x00
50 || (insn
& 0xf0) == 0x10
51 || (insn
& 0xf0) == 0x20
52 || (insn
& 0xf0) == 0x30
53 || ((insn
& 0xf0) == 0x80
54 && (insn
& 0x0c) >> 2 != (insn
& 0x03))
55 || (insn
& 0xf0) == 0x90
56 || (insn
& 0xf0) == 0xa0
57 || (insn
& 0xf0) == 0xb0
58 || (insn
& 0xff) == 0xeb
59 || (insn
& 0xff) == 0xf6
60 || (insn
& 0xff) == 0xfe)
66 /* These are two byte insns. */
67 else if ((insn
& 0xf0) == 0x40
68 || (insn
& 0xf0) == 0x50
69 || (insn
& 0xf0) == 0x60
70 || (insn
& 0xf0) == 0x70
71 || (insn
& 0xf0) == 0x80
72 || (insn
& 0xfc) == 0xd0
73 || (insn
& 0xfc) == 0xd4
74 || (insn
& 0xfc) == 0xd8
75 || (insn
& 0xfc) == 0xe0
76 || (insn
& 0xfc) == 0xe4
77 || (insn
& 0xff) == 0xe8
78 || (insn
& 0xff) == 0xe9
79 || (insn
& 0xff) == 0xea
80 || (insn
& 0xff) == 0xf0
81 || (insn
& 0xff) == 0xf1
82 || (insn
& 0xff) == 0xf2
83 || (insn
& 0xff) == 0xf3)
85 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
88 (*info
->memory_error_func
) (status
, memaddr
, info
);
91 insn
= bfd_getb16 (buffer
);
95 /* These are three byte insns with a 16bit operand in little
97 else if ((insn
& 0xf0) == 0xc0
98 || (insn
& 0xfc) == 0xdc
99 || (insn
& 0xfc) == 0xec
100 || (insn
& 0xff) == 0xf8
101 || (insn
& 0xff) == 0xf9
102 || (insn
& 0xff) == 0xfa
103 || (insn
& 0xff) == 0xfb
104 || (insn
& 0xff) == 0xfc
105 || (insn
& 0xff) == 0xfd)
107 status
= (*info
->read_memory_func
) (memaddr
+ 1, buffer
, 2, info
);
110 (*info
->memory_error_func
) (status
, memaddr
, info
);
114 insn
|= bfd_getl16 (buffer
);
118 /* These are three byte insns too, but we don't have to mess with
120 else if ((insn
& 0xff) == 0xf5)
122 status
= (*info
->read_memory_func
) (memaddr
+ 1, buffer
, 2, info
);
125 (*info
->memory_error_func
) (status
, memaddr
, info
);
129 insn
|= bfd_getb16 (buffer
);
134 /* These are four byte insns. */
135 else if ((insn
& 0xff) == 0xf7)
137 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
140 (*info
->memory_error_func
) (status
, memaddr
, info
);
143 insn
= bfd_getb16 (buffer
);
145 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 2, info
);
148 (*info
->memory_error_func
) (status
, memaddr
, info
);
151 insn
|= bfd_getl16 (buffer
);
156 /* These are five byte insns. */
157 else if ((insn
& 0xff) == 0xf4)
159 status
= (*info
->read_memory_func
) (memaddr
, buffer
, 2, info
);
162 (*info
->memory_error_func
) (status
, memaddr
, info
);
165 insn
= bfd_getb16 (buffer
);
168 status
= (*info
->read_memory_func
) (memaddr
+ 4, buffer
, 1, info
);
171 (*info
->memory_error_func
) (status
, memaddr
, info
);
174 insn
|= *(unsigned char *)buffer
<< 8;
176 status
= (*info
->read_memory_func
) (memaddr
+ 3, buffer
, 1, info
);
179 (*info
->memory_error_func
) (status
, memaddr
, info
);
182 insn
|= *(unsigned char *)buffer
;
184 status
= (*info
->read_memory_func
) (memaddr
+ 2, buffer
, 1, info
);
187 (*info
->memory_error_func
) (status
, memaddr
, info
);
190 extension
= *(unsigned char *)buffer
;
196 disassemble (memaddr
, info
, insn
, extension
, consume
);
202 disassemble (memaddr
, info
, insn
, extension
, size
)
204 struct disassemble_info
*info
;
206 unsigned long extension
;
209 struct mn10200_opcode
*op
= (struct mn10200_opcode
*)mn10200_opcodes
;
210 const struct mn10200_operand
*operand
;
213 /* Find the opcode. */
216 int mysize
, extra_shift
;
218 if (op
->format
== FMT_1
)
220 else if (op
->format
== FMT_2
221 || op
->format
== FMT_4
)
223 else if (op
->format
== FMT_3
224 || op
->format
== FMT_5
)
226 else if (op
->format
== FMT_6
)
228 else if (op
->format
== FMT_7
)
233 if (op
->format
== FMT_2
|| op
->format
== FMT_5
)
235 else if (op
->format
== FMT_3
236 || op
->format
== FMT_6
237 || op
->format
== FMT_7
)
242 if ((op
->mask
& insn
) == op
->opcode
245 const unsigned char *opindex_ptr
;
246 unsigned int nocomma
;
250 (*info
->fprintf_func
) (info
->stream
, "%s\t", op
->name
);
252 /* Now print the operands. */
253 for (opindex_ptr
= op
->operands
, nocomma
= 1;
259 operand
= &mn10200_operands
[*opindex_ptr
];
261 if ((operand
->flags
& MN10200_OPERAND_EXTENDED
) != 0)
263 value
= (insn
& 0xffff) << 8;
268 value
= ((insn
>> (operand
->shift
))
269 & ((1 << operand
->bits
) - 1));
272 if ((operand
->flags
& MN10200_OPERAND_SIGNED
) != 0)
273 value
= ((long)(value
<< (32 - operand
->bits
))
274 >> (32 - operand
->bits
));
278 || ((operand
->flags
& MN10200_OPERAND_PAREN
) == 0)))
279 (*info
->fprintf_func
) (info
->stream
, ",");
283 if ((operand
->flags
& MN10200_OPERAND_DREG
) != 0)
285 value
= ((insn
>> (operand
->shift
+ extra_shift
))
286 & ((1 << operand
->bits
) - 1));
287 (*info
->fprintf_func
) (info
->stream
, "d%d", value
);
290 else if ((operand
->flags
& MN10200_OPERAND_AREG
) != 0)
292 value
= ((insn
>> (operand
->shift
+ extra_shift
))
293 & ((1 << operand
->bits
) - 1));
294 (*info
->fprintf_func
) (info
->stream
, "a%d", value
);
297 else if ((operand
->flags
& MN10200_OPERAND_PSW
) != 0)
298 (*info
->fprintf_func
) (info
->stream
, "psw");
300 else if ((operand
->flags
& MN10200_OPERAND_MDR
) != 0)
301 (*info
->fprintf_func
) (info
->stream
, "mdr");
303 else if ((operand
->flags
& MN10200_OPERAND_PAREN
) != 0)
306 (*info
->fprintf_func
) (info
->stream
, ")");
309 (*info
->fprintf_func
) (info
->stream
, "(");
315 else if ((operand
->flags
& MN10200_OPERAND_PCREL
) != 0)
316 (*info
->print_address_func
) ((value
+ memaddr
) & 0xffffff, info
);
318 else if ((operand
->flags
& MN10200_OPERAND_MEMADDR
) != 0)
319 (*info
->print_address_func
) (value
, info
);
322 (*info
->fprintf_func
) (info
->stream
, "%d", value
);
332 (*info
->fprintf_func
) (info
->stream
, "unknown\t0x%04x", insn
);
This page took 0.054842 seconds and 4 git commands to generate.