ab2fed96512c94212601a6b8a1a653323d9edad2
[deliverable/binutils-gdb.git] / opcodes / m10300-dis.c
1 /* Disassemble MN10300 instructions.
2 Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
3
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.
8
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.
13
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. */
17
18
19 #include <stdio.h>
20
21 #include "ansidecl.h"
22 #include "opcode/mn10300.h"
23 #include "dis-asm.h"
24 #include "opintl.h"
25
26 static void disassemble PARAMS ((bfd_vma, struct disassemble_info *,
27 unsigned long insn, unsigned int));
28
29 int
30 print_insn_mn10300 (memaddr, info)
31 bfd_vma memaddr;
32 struct disassemble_info *info;
33 {
34 int status;
35 bfd_byte buffer[4];
36 unsigned long insn;
37 unsigned int consume;
38
39 /* First figure out how big the opcode is. */
40 status = (*info->read_memory_func) (memaddr, buffer, 1, info);
41 if (status != 0)
42 {
43 (*info->memory_error_func) (status, memaddr, info);
44 return -1;
45 }
46 insn = *(unsigned char *) buffer;
47
48 /* These are one byte insns. */
49 if ((insn & 0xf3) == 0x00
50 || (insn & 0xf0) == 0x10
51 || (insn & 0xfc) == 0x3c
52 || (insn & 0xf3) == 0x41
53 || (insn & 0xf3) == 0x40
54 || (insn & 0xfc) == 0x50
55 || (insn & 0xfc) == 0x54
56 || (insn & 0xf0) == 0x60
57 || (insn & 0xf0) == 0x70
58 || ((insn & 0xf0) == 0x80
59 && (insn & 0x0c) >> 2 != (insn & 0x03))
60 || ((insn & 0xf0) == 0x90
61 && (insn & 0x0c) >> 2 != (insn & 0x03))
62 || ((insn & 0xf0) == 0xa0
63 && (insn & 0x0c) >> 2 != (insn & 0x03))
64 || ((insn & 0xf0) == 0xb0
65 && (insn & 0x0c) >> 2 != (insn & 0x03))
66 || (insn & 0xff) == 0xcb
67 || (insn & 0xfc) == 0xd0
68 || (insn & 0xfc) == 0xd4
69 || (insn & 0xfc) == 0xd8
70 || (insn & 0xf0) == 0xe0
71 || (insn & 0xff) == 0xff)
72 {
73 consume = 1;
74 }
75
76 /* These are two byte insns. */
77 else if ((insn & 0xf0) == 0x80
78 || (insn & 0xf0) == 0x90
79 || (insn & 0xf0) == 0xa0
80 || (insn & 0xf0) == 0xb0
81 || (insn & 0xfc) == 0x20
82 || (insn & 0xfc) == 0x28
83 || (insn & 0xf3) == 0x43
84 || (insn & 0xf3) == 0x42
85 || (insn & 0xfc) == 0x58
86 || (insn & 0xfc) == 0x5c
87 || ((insn & 0xf0) == 0xc0
88 && (insn & 0xff) != 0xcb
89 && (insn & 0xff) != 0xcc
90 && (insn & 0xff) != 0xcd)
91 || (insn & 0xff) == 0xf0
92 || (insn & 0xff) == 0xf1
93 || (insn & 0xff) == 0xf2
94 || (insn & 0xff) == 0xf3
95 || (insn & 0xff) == 0xf4
96 || (insn & 0xff) == 0xf5
97 || (insn & 0xff) == 0xf6)
98 {
99 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
100 if (status != 0)
101 {
102 (*info->memory_error_func) (status, memaddr, info);
103 return -1;
104 }
105 insn = bfd_getb16 (buffer);
106 consume = 2;
107 }
108
109 /* These are three byte insns. */
110 else if ((insn & 0xff) == 0xf8
111 || (insn & 0xff) == 0xcc
112 || (insn & 0xff) == 0xf9
113 || (insn & 0xf3) == 0x01
114 || (insn & 0xf3) == 0x02
115 || (insn & 0xf3) == 0x03
116 || (insn & 0xfc) == 0x24
117 || (insn & 0xfc) == 0x2c
118 || (insn & 0xfc) == 0x30
119 || (insn & 0xfc) == 0x34
120 || (insn & 0xfc) == 0x38
121 || (insn & 0xff) == 0xde
122 || (insn & 0xff) == 0xdf
123 /* start-sanitize-am33 */
124 || (insn & 0xff) == 0xf9
125 /* end-sanitize-am33 */
126 || (insn & 0xff) == 0xcc)
127 {
128 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
129 if (status != 0)
130 {
131 (*info->memory_error_func) (status, memaddr, info);
132 return -1;
133 }
134 insn = bfd_getb16 (buffer);
135 insn <<= 8;
136 status = (*info->read_memory_func) (memaddr + 2, buffer, 1, info);
137 if (status != 0)
138 {
139 (*info->memory_error_func) (status, memaddr, info);
140 return -1;
141 }
142 insn |= *(unsigned char *)buffer;
143 consume = 3;
144 }
145
146 /* These are four byte insns. */
147 else if ((insn & 0xff) == 0xfa
148 || (insn & 0xff) == 0xfb)
149 {
150 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
151 if (status != 0)
152 {
153 (*info->memory_error_func) (status, memaddr, info);
154 return -1;
155 }
156 insn = bfd_getb32 (buffer);
157 consume = 4;
158 }
159
160 /* These are five byte insns. */
161 else if ((insn & 0xff) == 0xcd
162 || (insn & 0xff) == 0xdc)
163 {
164 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
165 if (status != 0)
166 {
167 (*info->memory_error_func) (status, memaddr, info);
168 return -1;
169 }
170 insn = bfd_getb32 (buffer);
171 consume = 5;
172 }
173
174 /* These are six byte insns. */
175 else if ((insn & 0xff) == 0xfd
176 || (insn & 0xff) == 0xfc)
177 {
178 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
179 if (status != 0)
180 {
181 (*info->memory_error_func) (status, memaddr, info);
182 return -1;
183 }
184
185 insn = bfd_getb32 (buffer);
186 consume = 6;
187 }
188
189 /* Else its a seven byte insns (in theory). */
190 else
191 {
192 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
193 if (status != 0)
194 {
195 (*info->memory_error_func) (status, memaddr, info);
196 return -1;
197 }
198
199 insn = bfd_getb32 (buffer);
200 consume = 7;
201 }
202
203 disassemble (memaddr, info, insn, consume);
204
205 return consume;
206 }
207
208 static void
209 disassemble (memaddr, info, insn, size)
210 bfd_vma memaddr;
211 struct disassemble_info *info;
212 unsigned long insn;
213 unsigned int size;
214 {
215 struct mn10300_opcode *op = (struct mn10300_opcode *)mn10300_opcodes;
216 const struct mn10300_operand *operand;
217 bfd_byte buffer[4];
218 unsigned long extension = 0;
219 int status, match = 0;
220
221 /* Find the opcode. */
222 while (op->name)
223 {
224 int mysize, extra_shift;
225
226 if (op->format == FMT_S0)
227 mysize = 1;
228 else if (op->format == FMT_S1
229 || op->format == FMT_D0)
230 mysize = 2;
231 else if (op->format == FMT_S2
232 || op->format == FMT_D1)
233 mysize = 3;
234 else if (op->format == FMT_S4)
235 mysize = 5;
236 else if (op->format == FMT_D2)
237 mysize = 4;
238 else if (op->format == FMT_D4)
239 mysize = 6;
240 /* start-sanitize-am33 */
241 else if (op->format == FMT_D6)
242 mysize = 3;
243 else if (op->format == FMT_D7 || op->format == FMT_D10)
244 mysize = 4;
245 else if (op->format == FMT_D8)
246 mysize = 6;
247 else if (op->format == FMT_D9)
248 mysize = 7;
249 /* end-sanitize-am33 */
250 else
251 mysize = 7;
252
253 if ((op->mask & insn) == op->opcode
254 && size == (unsigned int) mysize)
255 {
256 const unsigned char *opindex_ptr;
257 unsigned int nocomma;
258 int paren = 0;
259
260 if (op->format == FMT_D1 || op->format == FMT_S1)
261 extra_shift = 8;
262 else if (op->format == FMT_D2 || op->format == FMT_D4
263 || op->format == FMT_S2 || op->format == FMT_S4
264 || op->format == FMT_S6 || op->format == FMT_D5)
265 extra_shift = 16;
266 /* start-sanitize-am33 */
267 else if (op->format == FMT_D7
268 || op->format == FMT_D8
269 || op->format == FMT_D9)
270 extra_shift = 8;
271 /* end-sanitize-am33 */
272 else
273 extra_shift = 0;
274
275 if (size == 1 || size == 2)
276 {
277 extension = 0;
278 }
279 else if (size == 3
280 && (op->format == FMT_D1
281 || op->opcode == 0xdf0000
282 || op->opcode == 0xde0000))
283 {
284 extension = 0;
285 }
286 /* start-sanitize-am33 */
287 else if (size == 3
288 && op->format == FMT_D6)
289 {
290 extension = 0;
291 }
292 /* end-sanitize-am33 */
293 else if (size == 3)
294 {
295 insn &= 0xff0000;
296 status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
297 if (status != 0)
298 {
299 (*info->memory_error_func) (status, memaddr, info);
300 return;
301 }
302
303 insn |= bfd_getl16 (buffer);
304 extension = 0;
305 }
306 else if (size == 4
307 && (op->opcode == 0xfaf80000
308 || op->opcode == 0xfaf00000
309 || op->opcode == 0xfaf40000))
310 {
311 extension = 0;
312 }
313 /* start-sanitize-am33 */
314 else if (size == 4
315 && op->format == FMT_D7)
316 {
317 extension = 0;
318 }
319 /* end-sanitize-am33 */
320 else if (size == 4)
321 {
322 insn &= 0xffff0000;
323 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
324 if (status != 0)
325 {
326 (*info->memory_error_func) (status, memaddr, info);
327 return;
328 }
329
330 insn |= bfd_getl16 (buffer);
331 extension = 0;
332 }
333 else if (size == 5 && op->opcode == 0xdc000000)
334 {
335 unsigned long temp = 0;
336 status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
337 if (status != 0)
338 {
339 (*info->memory_error_func) (status, memaddr, info);
340 return;
341 }
342 temp |= bfd_getl32 (buffer);
343
344 insn &= 0xff000000;
345 insn |= (temp & 0xffffff00) >> 8;
346 extension = temp & 0xff;
347 }
348 else if (size == 5)
349 {
350 unsigned long temp = 0;
351 status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
352 if (status != 0)
353 {
354 (*info->memory_error_func) (status, memaddr, info);
355 return;
356 }
357 temp |= bfd_getl16 (buffer);
358
359 insn &= 0xff0000ff;
360 insn |= temp << 8;
361
362 status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
363 if (status != 0)
364 {
365 (*info->memory_error_func) (status, memaddr, info);
366 return;
367 }
368 extension = *(unsigned char *)buffer;
369 }
370 /* start-sanitize-am33 */
371 else if (size == 6 && op->format == FMT_D8)
372 {
373 insn &= 0xffffff00;
374 status = (*info->read_memory_func) (memaddr + 5, buffer, 1, info);
375 if (status != 0)
376 {
377 (*info->memory_error_func) (status, memaddr, info);
378 return;
379 }
380 insn |= *(unsigned char *)buffer;
381
382 status = (*info->read_memory_func) (memaddr + 3, buffer, 2, info);
383 if (status != 0)
384 {
385 (*info->memory_error_func) (status, memaddr, info);
386 return;
387 }
388 extension = bfd_getl16 (buffer);
389 }
390 /* end-sanitize-am33 */
391 else if (size == 6)
392 {
393 unsigned long temp = 0;
394 status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
395 if (status != 0)
396 {
397 (*info->memory_error_func) (status, memaddr, info);
398 return;
399 }
400 temp |= bfd_getl32 (buffer);
401
402 insn &= 0xffff0000;
403 insn |= (temp >> 16) & 0xffff;
404 extension = temp & 0xffff;
405 }
406 /* start-sanitize-am33 */
407 else if (size == 7 && op->format == FMT_D9)
408 {
409 insn &= 0xffffff00;
410 status = (*info->read_memory_func) (memaddr + 3, buffer, 4, info);
411 if (status != 0)
412 {
413 (*info->memory_error_func) (status, memaddr, info);
414 return;
415 }
416 extension = bfd_getl32 (buffer);
417 insn |= (extension & 0xff000000) >> 24;
418 extension &= 0xffffff;
419 }
420 /* end-sanitize-am33 */
421 else if (size == 7 && op->opcode == 0xdd000000)
422 {
423 unsigned long temp = 0;
424 status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
425 if (status != 0)
426 {
427 (*info->memory_error_func) (status, memaddr, info);
428 return;
429 }
430 temp |= bfd_getl32 (buffer);
431
432 insn &= 0xff000000;
433 insn |= (temp >> 8) & 0xffffff;
434 extension = (temp & 0xff) << 16;
435
436 status = (*info->read_memory_func) (memaddr + 5, buffer, 2, info);
437 if (status != 0)
438 {
439 (*info->memory_error_func) (status, memaddr, info);
440 return;
441 }
442 extension |= bfd_getb16 (buffer);
443 }
444 else if (size == 7)
445 {
446 unsigned long temp = 0;
447 status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
448 if (status != 0)
449 {
450 (*info->memory_error_func) (status, memaddr, info);
451 return;
452 }
453 temp |= bfd_getl32 (buffer);
454
455 insn &= 0xffff0000;
456 insn |= (temp >> 16) & 0xffff;
457 extension = (temp & 0xffff) << 8;
458
459 status = (*info->read_memory_func) (memaddr + 6, buffer, 1, info);
460 if (status != 0)
461 {
462 (*info->memory_error_func) (status, memaddr, info);
463 return;
464 }
465 extension |= *(unsigned char *)buffer;
466 }
467
468 match = 1;
469 (*info->fprintf_func) (info->stream, "%s\t", op->name);
470
471 /* Now print the operands. */
472 for (opindex_ptr = op->operands, nocomma = 1;
473 *opindex_ptr != 0;
474 opindex_ptr++)
475 {
476 unsigned long value;
477
478 operand = &mn10300_operands[*opindex_ptr];
479
480 if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
481 {
482 unsigned long temp;
483 value = insn & ((1 << operand->bits) - 1);
484 value <<= (32 - operand->bits);
485 temp = extension >> operand->shift;
486 temp &= ((1 << (32 - operand->bits)) - 1);
487 value |= temp;
488 }
489 /* start-sanitize-am33 */
490 else if ((operand->flags & MN10300_OPERAND_24BIT) != 0)
491 {
492 unsigned long temp;
493 value = insn & ((1 << operand->bits) - 1);
494 value <<= (24 - operand->bits);
495 temp = extension >> operand->shift;
496 temp &= ((1 << (24 - operand->bits)) - 1);
497 value |= temp;
498 if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
499 value = ((value & 0xffffff) ^ (~0x7fffff)) + 0x800000;
500 }
501 /* end-sanitize-am33 */
502 else if ((operand->flags & MN10300_OPERAND_EXTENDED) != 0)
503 {
504 value = ((extension >> (operand->shift))
505 & ((1 << operand->bits) - 1));
506 }
507 else
508 {
509 value = ((insn >> (operand->shift))
510 & ((1 << operand->bits) - 1));
511 }
512
513 if ((operand->flags & MN10300_OPERAND_SIGNED) != 0
514 /* start-sanitize-am33 */
515 /* These are properly extended by the code above. */
516 && ((operand->flags & MN10300_OPERAND_24BIT) == 0)
517 /* end-sanitize-am33 */
518 )
519 value = ((long)(value << (32 - operand->bits))
520 >> (32 - operand->bits));
521
522 if (!nocomma
523 && (!paren
524 || ((operand->flags & MN10300_OPERAND_PAREN) == 0)))
525 (*info->fprintf_func) (info->stream, ",");
526
527 nocomma = 0;
528
529 if ((operand->flags & MN10300_OPERAND_DREG) != 0)
530 {
531 value = ((insn >> (operand->shift + extra_shift))
532 & ((1 << operand->bits) - 1));
533 (*info->fprintf_func) (info->stream, "d%d", value);
534 }
535
536 else if ((operand->flags & MN10300_OPERAND_AREG) != 0)
537 {
538 value = ((insn >> (operand->shift + extra_shift))
539 & ((1 << operand->bits) - 1));
540 (*info->fprintf_func) (info->stream, "a%d", value);
541 }
542
543 else if ((operand->flags & MN10300_OPERAND_SP) != 0)
544 (*info->fprintf_func) (info->stream, "sp");
545
546 else if ((operand->flags & MN10300_OPERAND_PSW) != 0)
547 (*info->fprintf_func) (info->stream, "psw");
548
549 else if ((operand->flags & MN10300_OPERAND_MDR) != 0)
550 (*info->fprintf_func) (info->stream, "mdr");
551
552 /* start-sanitize-am33 */
553 else if ((operand->flags & MN10300_OPERAND_RREG) != 0)
554 {
555 value = ((insn >> (operand->shift + extra_shift))
556 & ((1 << operand->bits) - 1));
557 (*info->fprintf_func) (info->stream, "r%d", value);
558 }
559
560 else if ((operand->flags & MN10300_OPERAND_XRREG) != 0)
561 {
562 value = ((insn >> (operand->shift + extra_shift))
563 & ((1 << operand->bits) - 1));
564 (*info->fprintf_func) (info->stream, "xr%d", value);
565 }
566
567 else if ((operand->flags & MN10300_OPERAND_USP) != 0)
568 (*info->fprintf_func) (info->stream, "usp");
569
570 else if ((operand->flags & MN10300_OPERAND_SSP) != 0)
571 (*info->fprintf_func) (info->stream, "ssp");
572
573 else if ((operand->flags & MN10300_OPERAND_MSP) != 0)
574 (*info->fprintf_func) (info->stream, "msp");
575
576 else if ((operand->flags & MN10300_OPERAND_PC) != 0)
577 (*info->fprintf_func) (info->stream, "pc");
578
579 else if ((operand->flags & MN10300_OPERAND_EPSW) != 0)
580 (*info->fprintf_func) (info->stream, "epsw");
581
582 else if ((operand->flags & MN10300_OPERAND_PLUS) != 0)
583 (*info->fprintf_func) (info->stream, "+");
584 /* end-sanitize-am33 */
585
586 else if ((operand->flags & MN10300_OPERAND_PAREN) != 0)
587 {
588 if (paren)
589 (*info->fprintf_func) (info->stream, ")");
590 else
591 {
592 (*info->fprintf_func) (info->stream, "(");
593 nocomma = 1;
594 }
595 paren = !paren;
596 }
597
598 else if ((operand->flags & MN10300_OPERAND_PCREL) != 0)
599 (*info->print_address_func) ((long) value + memaddr, info);
600
601 else if ((operand->flags & MN10300_OPERAND_MEMADDR) != 0)
602 (*info->print_address_func) (value, info);
603
604 else if ((operand->flags & MN10300_OPERAND_REG_LIST) != 0)
605 {
606 int comma = 0;
607
608 (*info->fprintf_func) (info->stream, "[");
609 if (value & 0x80)
610 {
611 (*info->fprintf_func) (info->stream, "d2");
612 comma = 1;
613 }
614
615 if (value & 0x40)
616 {
617 if (comma)
618 (*info->fprintf_func) (info->stream, ",");
619 (*info->fprintf_func) (info->stream, "d3");
620 comma = 1;
621 }
622
623 if (value & 0x20)
624 {
625 if (comma)
626 (*info->fprintf_func) (info->stream, ",");
627 (*info->fprintf_func) (info->stream, "a2");
628 comma = 1;
629 }
630
631 if (value & 0x10)
632 {
633 if (comma)
634 (*info->fprintf_func) (info->stream, ",");
635 (*info->fprintf_func) (info->stream, "a3");
636 comma = 1;
637 }
638
639 if (value & 0x08)
640 {
641 if (comma)
642 (*info->fprintf_func) (info->stream, ",");
643 (*info->fprintf_func) (info->stream, "other");
644 comma = 1;
645 }
646
647 /* start-sanitize-am33 */
648 if (value & 0x04)
649 {
650 if (comma)
651 (*info->fprintf_func) (info->stream, ",");
652 (*info->fprintf_func) (info->stream, "exreg0");
653 comma = 1;
654 }
655 if (value & 0x02)
656 {
657 if (comma)
658 (*info->fprintf_func) (info->stream, ",");
659 (*info->fprintf_func) (info->stream, "exreg1");
660 comma = 1;
661 }
662 if (value & 0x01)
663 {
664 if (comma)
665 (*info->fprintf_func) (info->stream, ",");
666 (*info->fprintf_func) (info->stream, "exother");
667 comma = 1;
668 }
669 /* end-sanitize-am33 */
670 (*info->fprintf_func) (info->stream, "]");
671 }
672
673 else
674 (*info->fprintf_func) (info->stream, "%d", value);
675 }
676 /* All done. */
677 break;
678 }
679 op++;
680 }
681
682 if (!match)
683 {
684 /* xgettext:c-format */
685 (*info->fprintf_func) (info->stream, _("unknown\t0x%04x"), insn);
686 }
687 }
This page took 0.081178 seconds and 3 git commands to generate.