Fix typo in previous delta
[binutils.git] / opcodes / m10300-dis.c
blob1d3637c704d0b534fc82783b4faf7536f02406dd
1 /* Disassemble MN10300 instructions.
2 Copyright 1996, 1997, 1998, 1999, 2000, 2001 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. */
19 #include <stdio.h>
21 #include "sysdep.h"
22 #include "opcode/mn10300.h"
23 #include "dis-asm.h"
24 #include "opintl.h"
26 static void disassemble PARAMS ((bfd_vma, struct disassemble_info *,
27 unsigned long insn, unsigned int));
29 #define HAVE_AM33_2 (info->mach == AM33_2)
30 #define HAVE_AM33 (info->mach == AM33 || HAVE_AM33_2)
31 #define HAVE_AM30 (info->mach == AM30)
33 int
34 print_insn_mn10300 (memaddr, info)
35 bfd_vma memaddr;
36 struct disassemble_info *info;
38 int status;
39 bfd_byte buffer[4];
40 unsigned long insn;
41 unsigned int consume;
43 /* First figure out how big the opcode is. */
44 status = (*info->read_memory_func) (memaddr, buffer, 1, info);
45 if (status != 0)
47 (*info->memory_error_func) (status, memaddr, info);
48 return -1;
50 insn = *(unsigned char *) buffer;
52 /* These are one byte insns. */
53 if ((insn & 0xf3) == 0x00
54 || (insn & 0xf0) == 0x10
55 || (insn & 0xfc) == 0x3c
56 || (insn & 0xf3) == 0x41
57 || (insn & 0xf3) == 0x40
58 || (insn & 0xfc) == 0x50
59 || (insn & 0xfc) == 0x54
60 || (insn & 0xf0) == 0x60
61 || (insn & 0xf0) == 0x70
62 || ((insn & 0xf0) == 0x80
63 && (insn & 0x0c) >> 2 != (insn & 0x03))
64 || ((insn & 0xf0) == 0x90
65 && (insn & 0x0c) >> 2 != (insn & 0x03))
66 || ((insn & 0xf0) == 0xa0
67 && (insn & 0x0c) >> 2 != (insn & 0x03))
68 || ((insn & 0xf0) == 0xb0
69 && (insn & 0x0c) >> 2 != (insn & 0x03))
70 || (insn & 0xff) == 0xcb
71 || (insn & 0xfc) == 0xd0
72 || (insn & 0xfc) == 0xd4
73 || (insn & 0xfc) == 0xd8
74 || (insn & 0xf0) == 0xe0
75 || (insn & 0xff) == 0xff)
77 consume = 1;
80 /* These are two byte insns. */
81 else if ((insn & 0xf0) == 0x80
82 || (insn & 0xf0) == 0x90
83 || (insn & 0xf0) == 0xa0
84 || (insn & 0xf0) == 0xb0
85 || (insn & 0xfc) == 0x20
86 || (insn & 0xfc) == 0x28
87 || (insn & 0xf3) == 0x43
88 || (insn & 0xf3) == 0x42
89 || (insn & 0xfc) == 0x58
90 || (insn & 0xfc) == 0x5c
91 || ((insn & 0xf0) == 0xc0
92 && (insn & 0xff) != 0xcb
93 && (insn & 0xff) != 0xcc
94 && (insn & 0xff) != 0xcd)
95 || (insn & 0xff) == 0xf0
96 || (insn & 0xff) == 0xf1
97 || (insn & 0xff) == 0xf2
98 || (insn & 0xff) == 0xf3
99 || (insn & 0xff) == 0xf4
100 || (insn & 0xff) == 0xf5
101 || (insn & 0xff) == 0xf6)
103 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
104 if (status != 0)
106 (*info->memory_error_func) (status, memaddr, info);
107 return -1;
109 insn = bfd_getb16 (buffer);
110 consume = 2;
113 /* These are three byte insns. */
114 else if ((insn & 0xff) == 0xf8
115 || (insn & 0xff) == 0xcc
116 || (insn & 0xff) == 0xf9
117 || (insn & 0xf3) == 0x01
118 || (insn & 0xf3) == 0x02
119 || (insn & 0xf3) == 0x03
120 || (insn & 0xfc) == 0x24
121 || (insn & 0xfc) == 0x2c
122 || (insn & 0xfc) == 0x30
123 || (insn & 0xfc) == 0x34
124 || (insn & 0xfc) == 0x38
125 || (insn & 0xff) == 0xde
126 || (insn & 0xff) == 0xdf
127 || (insn & 0xff) == 0xf9
128 || (insn & 0xff) == 0xcc)
130 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
131 if (status != 0)
133 (*info->memory_error_func) (status, memaddr, info);
134 return -1;
136 insn = bfd_getb16 (buffer);
137 insn <<= 8;
138 status = (*info->read_memory_func) (memaddr + 2, buffer, 1, info);
139 if (status != 0)
141 (*info->memory_error_func) (status, memaddr, info);
142 return -1;
144 insn |= *(unsigned char *) buffer;
145 consume = 3;
148 /* These are four byte insns. */
149 else if ((insn & 0xff) == 0xfa
150 || (insn & 0xff) == 0xf7
151 || (insn & 0xff) == 0xfb)
153 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
154 if (status != 0)
156 (*info->memory_error_func) (status, memaddr, info);
157 return -1;
159 insn = bfd_getb32 (buffer);
160 consume = 4;
163 /* These are five byte insns. */
164 else if ((insn & 0xff) == 0xcd
165 || (insn & 0xff) == 0xdc)
167 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
168 if (status != 0)
170 (*info->memory_error_func) (status, memaddr, info);
171 return -1;
173 insn = bfd_getb32 (buffer);
174 consume = 5;
177 /* These are six byte insns. */
178 else if ((insn & 0xff) == 0xfd
179 || (insn & 0xff) == 0xfc)
181 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
182 if (status != 0)
184 (*info->memory_error_func) (status, memaddr, info);
185 return -1;
188 insn = bfd_getb32 (buffer);
189 consume = 6;
192 /* Else its a seven byte insns (in theory). */
193 else
195 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
196 if (status != 0)
198 (*info->memory_error_func) (status, memaddr, info);
199 return -1;
202 insn = bfd_getb32 (buffer);
203 consume = 7;
204 /* Handle the 5-byte extended instruction codes. */
205 if ((insn & 0xfff80000) == 0xfe800000)
206 consume = 5;
209 disassemble (memaddr, info, insn, consume);
211 return consume;
214 static void
215 disassemble (memaddr, info, insn, size)
216 bfd_vma memaddr;
217 struct disassemble_info *info;
218 unsigned long insn;
219 unsigned int size;
221 struct mn10300_opcode *op = (struct mn10300_opcode *)mn10300_opcodes;
222 const struct mn10300_operand *operand;
223 bfd_byte buffer[4];
224 unsigned long extension = 0;
225 int status, match = 0;
227 /* Find the opcode. */
228 while (op->name)
230 int mysize, extra_shift;
232 if (op->format == FMT_S0)
233 mysize = 1;
234 else if (op->format == FMT_S1
235 || op->format == FMT_D0)
236 mysize = 2;
237 else if (op->format == FMT_S2
238 || op->format == FMT_D1)
239 mysize = 3;
240 else if (op->format == FMT_S4)
241 mysize = 5;
242 else if (op->format == FMT_D2)
243 mysize = 4;
244 else if (op->format == FMT_D3)
245 mysize = 5;
246 else if (op->format == FMT_D4)
247 mysize = 6;
248 else if (op->format == FMT_D6)
249 mysize = 3;
250 else if (op->format == FMT_D7 || op->format == FMT_D10)
251 mysize = 4;
252 else if (op->format == FMT_D8)
253 mysize = 6;
254 else if (op->format == FMT_D9)
255 mysize = 7;
256 else
257 mysize = 7;
259 if ((op->mask & insn) == op->opcode
260 && size == (unsigned int) mysize
261 && (op->machine == 0
262 || (op->machine == AM33_2 && HAVE_AM33_2)
263 || (op->machine == AM33 && HAVE_AM33)
264 || (op->machine == AM30 && HAVE_AM30)))
266 const unsigned char *opindex_ptr;
267 unsigned int nocomma;
268 int paren = 0;
270 if (op->format == FMT_D1 || op->format == FMT_S1)
271 extra_shift = 8;
272 else if (op->format == FMT_D2 || op->format == FMT_D4
273 || op->format == FMT_S2 || op->format == FMT_S4
274 || op->format == FMT_S6 || op->format == FMT_D5)
275 extra_shift = 16;
276 else if (op->format == FMT_D7
277 || op->format == FMT_D8
278 || op->format == FMT_D9)
279 extra_shift = 8;
280 else
281 extra_shift = 0;
283 if (size == 1 || size == 2)
285 extension = 0;
287 else if (size == 3
288 && (op->format == FMT_D1
289 || op->opcode == 0xdf0000
290 || op->opcode == 0xde0000))
292 extension = 0;
294 else if (size == 3
295 && op->format == FMT_D6)
297 extension = 0;
299 else if (size == 3)
301 insn &= 0xff0000;
302 status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
303 if (status != 0)
305 (*info->memory_error_func) (status, memaddr, info);
306 return;
309 insn |= bfd_getl16 (buffer);
310 extension = 0;
312 else if (size == 4
313 && (op->opcode == 0xfaf80000
314 || op->opcode == 0xfaf00000
315 || op->opcode == 0xfaf40000))
317 extension = 0;
319 else if (size == 4
320 && (op->format == FMT_D7
321 || op->format == FMT_D10))
323 extension = 0;
325 else if (size == 4)
327 insn &= 0xffff0000;
328 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
329 if (status != 0)
331 (*info->memory_error_func) (status, memaddr, info);
332 return;
335 insn |= bfd_getl16 (buffer);
336 extension = 0;
338 else if (size == 5 && op->opcode == 0xdc000000)
340 unsigned long temp = 0;
341 status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
342 if (status != 0)
344 (*info->memory_error_func) (status, memaddr, info);
345 return;
347 temp |= bfd_getl32 (buffer);
349 insn &= 0xff000000;
350 insn |= (temp & 0xffffff00) >> 8;
351 extension = temp & 0xff;
353 else if (size == 5 && op->format == FMT_D3)
355 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
356 if (status != 0)
358 (*info->memory_error_func) (status, memaddr, info);
359 return;
361 insn &= 0xffff0000;
362 insn |= bfd_getl16 (buffer);
364 status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
365 if (status != 0)
367 (*info->memory_error_func) (status, memaddr, info);
368 return;
370 extension = *(unsigned char *) buffer;
372 else if (size == 5)
374 unsigned long temp = 0;
375 status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
376 if (status != 0)
378 (*info->memory_error_func) (status, memaddr, info);
379 return;
381 temp |= bfd_getl16 (buffer);
383 insn &= 0xff0000ff;
384 insn |= temp << 8;
386 status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
387 if (status != 0)
389 (*info->memory_error_func) (status, memaddr, info);
390 return;
392 extension = *(unsigned char *) buffer;
394 else if (size == 6 && op->format == FMT_D8)
396 insn &= 0xffffff00;
397 status = (*info->read_memory_func) (memaddr + 5, buffer, 1, info);
398 if (status != 0)
400 (*info->memory_error_func) (status, memaddr, info);
401 return;
403 insn |= *(unsigned char *) buffer;
405 status = (*info->read_memory_func) (memaddr + 3, buffer, 2, info);
406 if (status != 0)
408 (*info->memory_error_func) (status, memaddr, info);
409 return;
411 extension = bfd_getl16 (buffer);
413 else if (size == 6)
415 unsigned long temp = 0;
416 status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
417 if (status != 0)
419 (*info->memory_error_func) (status, memaddr, info);
420 return;
422 temp |= bfd_getl32 (buffer);
424 insn &= 0xffff0000;
425 insn |= (temp >> 16) & 0xffff;
426 extension = temp & 0xffff;
428 else if (size == 7 && op->format == FMT_D9)
430 insn &= 0xffffff00;
431 status = (*info->read_memory_func) (memaddr + 3, buffer, 4, info);
432 if (status != 0)
434 (*info->memory_error_func) (status, memaddr, info);
435 return;
437 extension = bfd_getl32 (buffer);
438 insn |= (extension & 0xff000000) >> 24;
439 extension &= 0xffffff;
441 else if (size == 7 && op->opcode == 0xdd000000)
443 unsigned long temp = 0;
444 status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
445 if (status != 0)
447 (*info->memory_error_func) (status, memaddr, info);
448 return;
450 temp |= bfd_getl32 (buffer);
452 insn &= 0xff000000;
453 insn |= (temp >> 8) & 0xffffff;
454 extension = (temp & 0xff) << 16;
456 status = (*info->read_memory_func) (memaddr + 5, buffer, 2, info);
457 if (status != 0)
459 (*info->memory_error_func) (status, memaddr, info);
460 return;
462 extension |= bfd_getb16 (buffer);
464 else if (size == 7)
466 unsigned long temp = 0;
467 status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
468 if (status != 0)
470 (*info->memory_error_func) (status, memaddr, info);
471 return;
473 temp |= bfd_getl32 (buffer);
475 insn &= 0xffff0000;
476 insn |= (temp >> 16) & 0xffff;
477 extension = (temp & 0xffff) << 8;
479 status = (*info->read_memory_func) (memaddr + 6, buffer, 1, info);
480 if (status != 0)
482 (*info->memory_error_func) (status, memaddr, info);
483 return;
485 extension |= *(unsigned char *) buffer;
488 match = 1;
489 (*info->fprintf_func) (info->stream, "%s\t", op->name);
491 /* Now print the operands. */
492 for (opindex_ptr = op->operands, nocomma = 1;
493 *opindex_ptr != 0;
494 opindex_ptr++)
496 unsigned long value;
498 operand = &mn10300_operands[*opindex_ptr];
500 /* If this operand is a PLUS (autoincrement), then do not emit
501 a comma before emitting the plus. */
502 if ((operand->flags & MN10300_OPERAND_PLUS) != 0)
503 nocomma = 1;
505 if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
507 unsigned long temp;
508 value = insn & ((1 << operand->bits) - 1);
509 value <<= (32 - operand->bits);
510 temp = extension >> operand->shift;
511 temp &= ((1 << (32 - operand->bits)) - 1);
512 value |= temp;
513 value = ((value ^ (((unsigned long) 1) << 31))
514 - (((unsigned long) 1) << 31));
516 else if ((operand->flags & MN10300_OPERAND_24BIT) != 0)
518 unsigned long temp;
519 value = insn & ((1 << operand->bits) - 1);
520 value <<= (24 - operand->bits);
521 temp = extension >> operand->shift;
522 temp &= ((1 << (24 - operand->bits)) - 1);
523 value |= temp;
524 if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
525 value = ((value & 0xffffff) ^ 0x800000) - 0x800000;
527 else if ((operand->flags & (MN10300_OPERAND_FSREG
528 | MN10300_OPERAND_FDREG)))
530 /* See m10300-opc.c just before #define FSM0 for an
531 explanation of these variables. Note that
532 FMT-implied shifts are not taken into account for
533 FP registers. */
534 unsigned long mask_low, mask_high;
535 int shl_low, shr_high, shl_high;
537 switch (operand->bits)
539 case 5:
540 /* Handle regular FP registers. */
541 if (operand->shift >= 0)
543 /* This is an `m' register. */
544 shl_low = operand->shift;
545 shl_high = 8 + (8 & shl_low) + (shl_low & 4) / 4;
547 else
549 /* This is an `n' register. */
550 shl_low = -operand->shift;
551 shl_high = shl_low / 4;
553 mask_low = 0x0f;
554 mask_high = 0x10;
555 shr_high = 4;
556 break;
558 case 3:
559 /* Handle accumulators. */
560 shl_low = -operand->shift;
561 shl_high = 0;
562 mask_low = 0x03;
563 mask_high = 0x04;
564 shr_high = 2;
565 break;
567 default:
568 abort ();
570 value = ((((insn >> shl_high) << shr_high) & mask_high)
571 | ((insn >> shl_low) & mask_low));
573 else if ((operand->flags & MN10300_OPERAND_EXTENDED) != 0)
575 value = ((extension >> (operand->shift))
576 & ((1 << operand->bits) - 1));
578 else
580 value = ((insn >> (operand->shift))
581 & ((1 << operand->bits) - 1));
584 if ((operand->flags & MN10300_OPERAND_SIGNED) != 0
585 /* These are properly extended by the code above. */
586 && ((operand->flags & MN10300_OPERAND_24BIT) == 0))
587 value = ((value ^ (((unsigned long) 1) << (operand->bits - 1)))
588 - (((unsigned long) 1) << (operand->bits - 1)));
590 if (!nocomma
591 && (!paren
592 || ((operand->flags & MN10300_OPERAND_PAREN) == 0)))
593 (*info->fprintf_func) (info->stream, ",");
595 nocomma = 0;
597 if ((operand->flags & MN10300_OPERAND_DREG) != 0)
599 value = ((insn >> (operand->shift + extra_shift))
600 & ((1 << operand->bits) - 1));
601 (*info->fprintf_func) (info->stream, "d%d", (int) value);
604 else if ((operand->flags & MN10300_OPERAND_AREG) != 0)
606 value = ((insn >> (operand->shift + extra_shift))
607 & ((1 << operand->bits) - 1));
608 (*info->fprintf_func) (info->stream, "a%d", (int) value);
611 else if ((operand->flags & MN10300_OPERAND_SP) != 0)
612 (*info->fprintf_func) (info->stream, "sp");
614 else if ((operand->flags & MN10300_OPERAND_PSW) != 0)
615 (*info->fprintf_func) (info->stream, "psw");
617 else if ((operand->flags & MN10300_OPERAND_MDR) != 0)
618 (*info->fprintf_func) (info->stream, "mdr");
620 else if ((operand->flags & MN10300_OPERAND_RREG) != 0)
622 value = ((insn >> (operand->shift + extra_shift))
623 & ((1 << operand->bits) - 1));
624 if (value < 8)
625 (*info->fprintf_func) (info->stream, "r%d", (int) value);
626 else if (value < 12)
627 (*info->fprintf_func) (info->stream, "a%d", (int) value - 8);
628 else
629 (*info->fprintf_func) (info->stream, "d%d", (int) value - 12);
632 else if ((operand->flags & MN10300_OPERAND_XRREG) != 0)
634 value = ((insn >> (operand->shift + extra_shift))
635 & ((1 << operand->bits) - 1));
636 if (value == 0)
637 (*info->fprintf_func) (info->stream, "sp", value);
638 else
639 (*info->fprintf_func) (info->stream, "xr%d", (int) value);
642 else if ((operand->flags & MN10300_OPERAND_FSREG) != 0)
643 (*info->fprintf_func) (info->stream, "fs%d", (int) value);
645 else if ((operand->flags & MN10300_OPERAND_FDREG) != 0)
646 (*info->fprintf_func) (info->stream, "fd%d", (int) value);
648 else if ((operand->flags & MN10300_OPERAND_FPCR) != 0)
649 (*info->fprintf_func) (info->stream, "fpcr");
651 else if ((operand->flags & MN10300_OPERAND_USP) != 0)
652 (*info->fprintf_func) (info->stream, "usp");
654 else if ((operand->flags & MN10300_OPERAND_SSP) != 0)
655 (*info->fprintf_func) (info->stream, "ssp");
657 else if ((operand->flags & MN10300_OPERAND_MSP) != 0)
658 (*info->fprintf_func) (info->stream, "msp");
660 else if ((operand->flags & MN10300_OPERAND_PC) != 0)
661 (*info->fprintf_func) (info->stream, "pc");
663 else if ((operand->flags & MN10300_OPERAND_EPSW) != 0)
664 (*info->fprintf_func) (info->stream, "epsw");
666 else if ((operand->flags & MN10300_OPERAND_PLUS) != 0)
667 (*info->fprintf_func) (info->stream, "+");
669 else if ((operand->flags & MN10300_OPERAND_PAREN) != 0)
671 if (paren)
672 (*info->fprintf_func) (info->stream, ")");
673 else
675 (*info->fprintf_func) (info->stream, "(");
676 nocomma = 1;
678 paren = !paren;
681 else if ((operand->flags & MN10300_OPERAND_PCREL) != 0)
682 (*info->print_address_func) ((long) value + memaddr, info);
684 else if ((operand->flags & MN10300_OPERAND_MEMADDR) != 0)
685 (*info->print_address_func) (value, info);
687 else if ((operand->flags & MN10300_OPERAND_REG_LIST) != 0)
689 int comma = 0;
691 (*info->fprintf_func) (info->stream, "[");
692 if (value & 0x80)
694 (*info->fprintf_func) (info->stream, "d2");
695 comma = 1;
698 if (value & 0x40)
700 if (comma)
701 (*info->fprintf_func) (info->stream, ",");
702 (*info->fprintf_func) (info->stream, "d3");
703 comma = 1;
706 if (value & 0x20)
708 if (comma)
709 (*info->fprintf_func) (info->stream, ",");
710 (*info->fprintf_func) (info->stream, "a2");
711 comma = 1;
714 if (value & 0x10)
716 if (comma)
717 (*info->fprintf_func) (info->stream, ",");
718 (*info->fprintf_func) (info->stream, "a3");
719 comma = 1;
722 if (value & 0x08)
724 if (comma)
725 (*info->fprintf_func) (info->stream, ",");
726 (*info->fprintf_func) (info->stream, "other");
727 comma = 1;
730 if (value & 0x04)
732 if (comma)
733 (*info->fprintf_func) (info->stream, ",");
734 (*info->fprintf_func) (info->stream, "exreg0");
735 comma = 1;
737 if (value & 0x02)
739 if (comma)
740 (*info->fprintf_func) (info->stream, ",");
741 (*info->fprintf_func) (info->stream, "exreg1");
742 comma = 1;
744 if (value & 0x01)
746 if (comma)
747 (*info->fprintf_func) (info->stream, ",");
748 (*info->fprintf_func) (info->stream, "exother");
749 comma = 1;
751 (*info->fprintf_func) (info->stream, "]");
754 else
755 (*info->fprintf_func) (info->stream, "%ld", (long) value);
757 /* All done. */
758 break;
760 op++;
763 if (!match)
765 /* xgettext:c-format */
766 (*info->fprintf_func) (info->stream, _("unknown\t0x%04x"), insn);