* arm-dis.c (print_insn_arm): Don't print instruction bytes.
[deliverable/binutils-gdb.git] / opcodes / mn10300-dis.c
CommitLineData
ae1b99e4 1/* Disassemble MN10300 instructions.
24e9036a 2 Copyright (C) 1996, 1997 Free Software Foundation, Inc.
e7c50cef
JL
3
4This program is free software; you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation; either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18
19#include <stdio.h>
20
21#include "ansidecl.h"
ae1b99e4 22#include "opcode/mn10300.h"
e7c50cef
JL
23#include "dis-asm.h"
24
4aa92185 25static void disassemble PARAMS ((bfd_vma, struct disassemble_info *,
77955104 26 unsigned long insn, unsigned int));
4aa92185 27
e7c50cef 28int
ae1b99e4 29print_insn_mn10300 (memaddr, info)
e7c50cef
JL
30 bfd_vma memaddr;
31 struct disassemble_info *info;
32{
4aa92185
JL
33 int status;
34 bfd_byte buffer[4];
35 unsigned long insn;
4aa92185
JL
36 unsigned int consume;
37
38 /* First figure out how big the opcode is. */
39 status = (*info->read_memory_func) (memaddr, buffer, 1, info);
40 if (status != 0)
41 {
42 (*info->memory_error_func) (status, memaddr, info);
43 return -1;
44 }
45 insn = *(unsigned char *) buffer;
46
d91028d2 47 /* These are one byte insns. */
4aa92185
JL
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)
70 {
4aa92185
JL
71 consume = 1;
72 }
73
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)
96 {
97 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
98 if (status != 0)
99 {
100 (*info->memory_error_func) (status, memaddr, info);
101 return -1;
102 }
103 insn = bfd_getb16 (buffer);
4aa92185
JL
104 consume = 2;
105 }
106
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)
122 {
123 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
124 if (status != 0)
125 {
126 (*info->memory_error_func) (status, memaddr, info);
127 return -1;
128 }
129 insn = bfd_getb16 (buffer);
130 insn <<= 8;
d91028d2
JL
131 status = (*info->read_memory_func) (memaddr + 2, buffer, 1, info);
132 if (status != 0)
133 {
134 (*info->memory_error_func) (status, memaddr, info);
135 return -1;
136 }
137 insn |= *(unsigned char *)buffer;
4aa92185
JL
138 consume = 3;
139 }
140
141 /* These are four byte insns. */
142 else if ((insn & 0xff) == 0xfa
143 || (insn & 0xff) == 0xfb)
144 {
145 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
146 if (status != 0)
147 {
148 (*info->memory_error_func) (status, memaddr, info);
149 return -1;
150 }
151 insn = bfd_getb32 (buffer);
4aa92185
JL
152 consume = 4;
153 }
154
155 /* These are five byte insns. */
156 else if ((insn & 0xff) == 0xcd
157 || (insn & 0xff) == 0xdc)
158 {
159 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
160 if (status != 0)
161 {
162 (*info->memory_error_func) (status, memaddr, info);
163 return -1;
164 }
165 insn = bfd_getb32 (buffer);
4aa92185
JL
166 consume = 5;
167 }
168
169 /* These are six byte insns. */
170 else if ((insn & 0xff) == 0xfd
171 || (insn & 0xff) == 0xfc)
172 {
173 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
174 if (status != 0)
175 {
176 (*info->memory_error_func) (status, memaddr, info);
177 return -1;
178 }
179
180 insn = bfd_getb32 (buffer);
4aa92185
JL
181 consume = 6;
182 }
183
184 /* Else its a seven byte insns (in theory). */
185 else
186 {
187 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
188 if (status != 0)
189 {
190 (*info->memory_error_func) (status, memaddr, info);
191 return -1;
192 }
193
194 insn = bfd_getb32 (buffer);
4aa92185
JL
195 consume = 7;
196 }
197
77955104 198 disassemble (memaddr, info, insn, consume);
4aa92185
JL
199
200 return consume;
201}
202
203static void
77955104 204disassemble (memaddr, info, insn, size)
4aa92185
JL
205 bfd_vma memaddr;
206 struct disassemble_info *info;
207 unsigned long insn;
4aa92185
JL
208 unsigned int size;
209{
210 struct mn10300_opcode *op = (struct mn10300_opcode *)mn10300_opcodes;
211 const struct mn10300_operand *operand;
77955104 212 bfd_byte buffer[4];
bc830321 213 unsigned long extension = 0;
77955104 214 int status, match = 0;
4aa92185
JL
215
216 /* Find the opcode. */
217 while (op->name)
218 {
d91028d2 219 int mysize, extra_shift;
4aa92185
JL
220
221 if (op->format == FMT_S0)
222 mysize = 1;
223 else if (op->format == FMT_S1
224 || op->format == FMT_D0)
225 mysize = 2;
226 else if (op->format == FMT_S2
227 || op->format == FMT_D1)
228 mysize = 3;
229 else if (op->format == FMT_S4)
230 mysize = 5;
231 else if (op->format == FMT_D2)
232 mysize = 4;
233 else if (op->format == FMT_D4)
234 mysize = 6;
235 else
236 mysize = 7;
237
238 if ((op->mask & insn) == op->opcode
239 && size == mysize)
240 {
241 const unsigned char *opindex_ptr;
83296990 242 unsigned int nocomma;
d91028d2 243 int paren = 0;
4aa92185 244
77955104
JL
245 if (op->format == FMT_D1 || op->format == FMT_S1)
246 extra_shift = 8;
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)
250 extra_shift = 16;
251 else
252 extra_shift = 0;
253
254 if (size == 1 || size == 2)
255 {
256 extension = 0;
257 }
258 else if (size == 3
259 && (op->format == FMT_D1
260 || op->opcode == 0xdf0000
261 || op->opcode == 0xde0000))
262 {
263 extension = 0;
264 }
265 else if (size == 3)
266 {
267 insn &= 0xff0000;
268 status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
269 if (status != 0)
270 {
271 (*info->memory_error_func) (status, memaddr, info);
272 return;
273 }
274
275 insn |= bfd_getl16 (buffer);
276 extension = 0;
277 }
278 else if (size == 4
279 && (op->opcode == 0xfaf80000
280 || op->opcode == 0xfaf00000
281 || op->opcode == 0xfaf40000))
282 {
283 extension = 0;
284 }
285 else if (size == 4)
286 {
287 insn &= 0xffff0000;
288 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
289 if (status != 0)
290 {
291 (*info->memory_error_func) (status, memaddr, info);
292 return;
293 }
294
295 insn |= bfd_getl16 (buffer);
296 extension = 0;
297 }
298 else if (size == 5 && op->opcode == 0xdc000000)
299 {
bc830321 300 unsigned long temp = 0;
77955104
JL
301 status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
302 if (status != 0)
303 {
304 (*info->memory_error_func) (status, memaddr, info);
305 return;
306 }
307 temp |= bfd_getl32 (buffer);
308
309 insn &= 0xff000000;
310 insn |= (temp & 0xffffff00) >> 8;
311 extension = temp & 0xff;
312 }
313 else if (size == 5)
314 {
bc830321 315 unsigned long temp = 0;
77955104
JL
316 status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
317 if (status != 0)
318 {
319 (*info->memory_error_func) (status, memaddr, info);
320 return;
321 }
322 temp |= bfd_getl16 (buffer);
323
324 insn &= 0xff0000ff;
325 insn |= temp << 8;
326
327 status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
328 if (status != 0)
329 {
330 (*info->memory_error_func) (status, memaddr, info);
331 return;
332 }
333 extension = *(unsigned char *)buffer;
334 }
335 else if (size == 6)
336 {
bc830321 337 unsigned long temp = 0;
77955104
JL
338 status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
339 if (status != 0)
340 {
341 (*info->memory_error_func) (status, memaddr, info);
342 return;
343 }
344 temp |= bfd_getl32 (buffer);
345
346 insn &= 0xffff0000;
347 insn |= (temp >> 16) & 0xffff;
348 extension = temp & 0xffff;
349 }
350 else if (size == 7 && op->opcode == 0xdd000000)
351 {
bc830321 352 unsigned long temp = 0;
77955104
JL
353 status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
354 if (status != 0)
355 {
356 (*info->memory_error_func) (status, memaddr, info);
357 return;
358 }
359 temp |= bfd_getl32 (buffer);
360
361 insn &= 0xff000000;
362 insn |= (temp >> 8) & 0xffffff;
363 extension = (temp & 0xff) << 16;
364
365 status = (*info->read_memory_func) (memaddr + 5, buffer, 2, info);
366 if (status != 0)
367 {
368 (*info->memory_error_func) (status, memaddr, info);
369 return;
370 }
371 extension |= bfd_getb16 (buffer);
372 }
373 else if (size == 7)
374 {
bc830321 375 unsigned long temp = 0;
77955104
JL
376 status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
377 if (status != 0)
378 {
379 (*info->memory_error_func) (status, memaddr, info);
380 return;
381 }
382 temp |= bfd_getl32 (buffer);
383
384 insn &= 0xffff0000;
385 insn |= (temp >> 16) & 0xffff;
386 extension = (temp & 0xffff) << 8;
387
388 status = (*info->read_memory_func) (memaddr + 6, buffer, 1, info);
389 if (status != 0)
390 {
391 (*info->memory_error_func) (status, memaddr, info);
392 return;
393 }
394 extension |= *(unsigned char *)buffer;
395 }
396
4aa92185
JL
397 match = 1;
398 (*info->fprintf_func) (info->stream, "%s\t", op->name);
399
400 /* Now print the operands. */
d91028d2 401 for (opindex_ptr = op->operands, nocomma = 1;
4aa92185 402 *opindex_ptr != 0;
d91028d2 403 opindex_ptr++)
4aa92185
JL
404 {
405 unsigned long value;
406
407 operand = &mn10300_operands[*opindex_ptr];
408
f497f3ae
JL
409 if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
410 {
411 unsigned long temp;
412 value = insn & ((1 << operand->bits) - 1);
413 value <<= (32 - operand->bits);
414 temp = extension >> operand->shift;
83296990 415 temp &= ((1 << (32 - operand->bits)) - 1);
f497f3ae
JL
416 value |= temp;
417 }
418 else if ((operand->flags & MN10300_OPERAND_EXTENDED) != 0)
419 {
420 value = ((extension >> (operand->shift))
421 & ((1 << operand->bits) - 1));
422 }
423 else
424 {
425 value = ((insn >> (operand->shift))
426 & ((1 << operand->bits) - 1));
427 }
4aa92185
JL
428
429 if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
430 value = ((long)(value << (32 - operand->bits))
431 >> (32 - operand->bits));
432
d91028d2
JL
433 if (!nocomma
434 && (!paren
435 || ((operand->flags & MN10300_OPERAND_PAREN) == 0)))
436 (*info->fprintf_func) (info->stream, ",");
437
438 nocomma = 0;
439
440 if ((operand->flags & MN10300_OPERAND_DREG) != 0)
441 {
442 value = ((insn >> (operand->shift + extra_shift))
443 & ((1 << operand->bits) - 1));
4db788a6 444 (*info->fprintf_func) (info->stream, "d%d", value);
d91028d2
JL
445 }
446
447 else if ((operand->flags & MN10300_OPERAND_AREG) != 0)
448 {
449 value = ((insn >> (operand->shift + extra_shift))
450 & ((1 << operand->bits) - 1));
4db788a6 451 (*info->fprintf_func) (info->stream, "a%d", value);
d91028d2
JL
452 }
453
454 else if ((operand->flags & MN10300_OPERAND_SP) != 0)
4db788a6 455 (*info->fprintf_func) (info->stream, "sp");
d91028d2
JL
456
457 else if ((operand->flags & MN10300_OPERAND_PSW) != 0)
4db788a6 458 (*info->fprintf_func) (info->stream, "psw");
d91028d2
JL
459
460 else if ((operand->flags & MN10300_OPERAND_MDR) != 0)
4db788a6 461 (*info->fprintf_func) (info->stream, "mdr");
d91028d2
JL
462
463 else if ((operand->flags & MN10300_OPERAND_PAREN) != 0)
464 {
465 if (paren)
466 (*info->fprintf_func) (info->stream, ")");
467 else
468 {
469 (*info->fprintf_func) (info->stream, "(");
470 nocomma = 1;
471 }
472 paren = !paren;
473 }
474
aa9c04cd
JL
475 else if ((operand->flags & MN10300_OPERAND_PCREL) != 0)
476 (*info->print_address_func) (value + memaddr, info);
477
478 else if ((operand->flags & MN10300_OPERAND_MEMADDR) != 0)
479 (*info->print_address_func) (value, info);
480
f0e98103
JL
481 else if ((operand->flags & MN10300_OPERAND_REG_LIST) != 0)
482 {
483 int comma = 0;
484
485 (*info->fprintf_func) (info->stream, "[");
486 if (value & 0x80)
487 {
4db788a6 488 (*info->fprintf_func) (info->stream, "d2");
f0e98103
JL
489 comma = 1;
490 }
491
492 if (value & 0x40)
493 {
494 if (comma)
495 (*info->fprintf_func) (info->stream, ",");
4db788a6 496 (*info->fprintf_func) (info->stream, "d3");
f0e98103
JL
497 comma = 1;
498 }
499
500 if (value & 0x20)
501 {
502 if (comma)
503 (*info->fprintf_func) (info->stream, ",");
4db788a6 504 (*info->fprintf_func) (info->stream, "a2");
f0e98103
JL
505 comma = 1;
506 }
507
508 if (value & 0x10)
509 {
510 if (comma)
511 (*info->fprintf_func) (info->stream, ",");
4db788a6 512 (*info->fprintf_func) (info->stream, "a3");
f0e98103
JL
513 comma = 1;
514 }
515
516 if (value & 0x08)
517 {
518 if (comma)
519 (*info->fprintf_func) (info->stream, ",");
4db788a6 520 (*info->fprintf_func) (info->stream, "other");
f0e98103
JL
521 comma = 1;
522 }
523 (*info->fprintf_func) (info->stream, "]");
524 }
525
d91028d2
JL
526 else
527 (*info->fprintf_func) (info->stream, "%d", value);
528 }
4aa92185
JL
529 /* All done. */
530 break;
531 }
532 op++;
533 }
534
535 if (!match)
536 {
537 (*info->fprintf_func) (info->stream, "unknown\t0x%04x", insn);
538 }
e7c50cef 539}
This page took 0.198239 seconds and 4 git commands to generate.