This commit was generated by cvs2svn to track changes on a CVS vendor
[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 /* start-sanitize-am33 */
149 || (insn & 0xff) == 0xf7
150 /* end-sanitize-am33 */
151 || (insn & 0xff) == 0xfb)
152 {
153 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
154 if (status != 0)
155 {
156 (*info->memory_error_func) (status, memaddr, info);
157 return -1;
158 }
159 insn = bfd_getb32 (buffer);
160 consume = 4;
161 }
162
163 /* These are five byte insns. */
164 else if ((insn & 0xff) == 0xcd
165 || (insn & 0xff) == 0xdc)
166 {
167 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
168 if (status != 0)
169 {
170 (*info->memory_error_func) (status, memaddr, info);
171 return -1;
172 }
173 insn = bfd_getb32 (buffer);
174 consume = 5;
175 }
176
177 /* These are six byte insns. */
178 else if ((insn & 0xff) == 0xfd
179 || (insn & 0xff) == 0xfc)
180 {
181 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
182 if (status != 0)
183 {
184 (*info->memory_error_func) (status, memaddr, info);
185 return -1;
186 }
187
188 insn = bfd_getb32 (buffer);
189 consume = 6;
190 }
191
192 /* Else its a seven byte insns (in theory). */
193 else
194 {
195 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
196 if (status != 0)
197 {
198 (*info->memory_error_func) (status, memaddr, info);
199 return -1;
200 }
201
202 insn = bfd_getb32 (buffer);
203 consume = 7;
204 }
205
206 disassemble (memaddr, info, insn, consume);
207
208 return consume;
209 }
210
211 static void
212 disassemble (memaddr, info, insn, size)
213 bfd_vma memaddr;
214 struct disassemble_info *info;
215 unsigned long insn;
216 unsigned int size;
217 {
218 struct mn10300_opcode *op = (struct mn10300_opcode *)mn10300_opcodes;
219 const struct mn10300_operand *operand;
220 bfd_byte buffer[4];
221 unsigned long extension = 0;
222 int status, match = 0;
223
224 /* Find the opcode. */
225 while (op->name)
226 {
227 int mysize, extra_shift;
228
229 if (op->format == FMT_S0)
230 mysize = 1;
231 else if (op->format == FMT_S1
232 || op->format == FMT_D0)
233 mysize = 2;
234 else if (op->format == FMT_S2
235 || op->format == FMT_D1)
236 mysize = 3;
237 else if (op->format == FMT_S4)
238 mysize = 5;
239 else if (op->format == FMT_D2)
240 mysize = 4;
241 else if (op->format == FMT_D4)
242 mysize = 6;
243 /* start-sanitize-am33 */
244 else if (op->format == FMT_D6)
245 mysize = 3;
246 else if (op->format == FMT_D7 || op->format == FMT_D10)
247 mysize = 4;
248 else if (op->format == FMT_D8)
249 mysize = 6;
250 else if (op->format == FMT_D9)
251 mysize = 7;
252 /* end-sanitize-am33 */
253 else
254 mysize = 7;
255
256 if ((op->mask & insn) == op->opcode
257 && size == (unsigned int) mysize
258 && (op->machine == 0
259 || op->machine == info->mach))
260 {
261 const unsigned char *opindex_ptr;
262 unsigned int nocomma;
263 int paren = 0;
264
265 if (op->format == FMT_D1 || op->format == FMT_S1)
266 extra_shift = 8;
267 else if (op->format == FMT_D2 || op->format == FMT_D4
268 || op->format == FMT_S2 || op->format == FMT_S4
269 || op->format == FMT_S6 || op->format == FMT_D5)
270 extra_shift = 16;
271 /* start-sanitize-am33 */
272 else if (op->format == FMT_D7
273 || op->format == FMT_D8
274 || op->format == FMT_D9)
275 extra_shift = 8;
276 /* end-sanitize-am33 */
277 else
278 extra_shift = 0;
279
280 if (size == 1 || size == 2)
281 {
282 extension = 0;
283 }
284 else if (size == 3
285 && (op->format == FMT_D1
286 || op->opcode == 0xdf0000
287 || op->opcode == 0xde0000))
288 {
289 extension = 0;
290 }
291 /* start-sanitize-am33 */
292 else if (size == 3
293 && op->format == FMT_D6)
294 {
295 extension = 0;
296 }
297 /* end-sanitize-am33 */
298 else if (size == 3)
299 {
300 insn &= 0xff0000;
301 status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
302 if (status != 0)
303 {
304 (*info->memory_error_func) (status, memaddr, info);
305 return;
306 }
307
308 insn |= bfd_getl16 (buffer);
309 extension = 0;
310 }
311 else if (size == 4
312 && (op->opcode == 0xfaf80000
313 || op->opcode == 0xfaf00000
314 || op->opcode == 0xfaf40000))
315 {
316 extension = 0;
317 }
318 /* start-sanitize-am33 */
319 else if (size == 4
320 && (op->format == FMT_D7
321 || op->format == FMT_D10))
322 {
323 extension = 0;
324 }
325 /* end-sanitize-am33 */
326 else if (size == 4)
327 {
328 insn &= 0xffff0000;
329 status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
330 if (status != 0)
331 {
332 (*info->memory_error_func) (status, memaddr, info);
333 return;
334 }
335
336 insn |= bfd_getl16 (buffer);
337 extension = 0;
338 }
339 else if (size == 5 && op->opcode == 0xdc000000)
340 {
341 unsigned long temp = 0;
342 status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
343 if (status != 0)
344 {
345 (*info->memory_error_func) (status, memaddr, info);
346 return;
347 }
348 temp |= bfd_getl32 (buffer);
349
350 insn &= 0xff000000;
351 insn |= (temp & 0xffffff00) >> 8;
352 extension = temp & 0xff;
353 }
354 else if (size == 5)
355 {
356 unsigned long temp = 0;
357 status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
358 if (status != 0)
359 {
360 (*info->memory_error_func) (status, memaddr, info);
361 return;
362 }
363 temp |= bfd_getl16 (buffer);
364
365 insn &= 0xff0000ff;
366 insn |= temp << 8;
367
368 status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
369 if (status != 0)
370 {
371 (*info->memory_error_func) (status, memaddr, info);
372 return;
373 }
374 extension = *(unsigned char *)buffer;
375 }
376 /* start-sanitize-am33 */
377 else if (size == 6 && op->format == FMT_D8)
378 {
379 insn &= 0xffffff00;
380 status = (*info->read_memory_func) (memaddr + 5, buffer, 1, info);
381 if (status != 0)
382 {
383 (*info->memory_error_func) (status, memaddr, info);
384 return;
385 }
386 insn |= *(unsigned char *)buffer;
387
388 status = (*info->read_memory_func) (memaddr + 3, buffer, 2, info);
389 if (status != 0)
390 {
391 (*info->memory_error_func) (status, memaddr, info);
392 return;
393 }
394 extension = bfd_getl16 (buffer);
395 }
396 /* end-sanitize-am33 */
397 else if (size == 6)
398 {
399 unsigned long temp = 0;
400 status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
401 if (status != 0)
402 {
403 (*info->memory_error_func) (status, memaddr, info);
404 return;
405 }
406 temp |= bfd_getl32 (buffer);
407
408 insn &= 0xffff0000;
409 insn |= (temp >> 16) & 0xffff;
410 extension = temp & 0xffff;
411 }
412 /* start-sanitize-am33 */
413 else if (size == 7 && op->format == FMT_D9)
414 {
415 insn &= 0xffffff00;
416 status = (*info->read_memory_func) (memaddr + 3, buffer, 4, info);
417 if (status != 0)
418 {
419 (*info->memory_error_func) (status, memaddr, info);
420 return;
421 }
422 extension = bfd_getl32 (buffer);
423 insn |= (extension & 0xff000000) >> 24;
424 extension &= 0xffffff;
425 }
426 /* end-sanitize-am33 */
427 else if (size == 7 && op->opcode == 0xdd000000)
428 {
429 unsigned long temp = 0;
430 status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
431 if (status != 0)
432 {
433 (*info->memory_error_func) (status, memaddr, info);
434 return;
435 }
436 temp |= bfd_getl32 (buffer);
437
438 insn &= 0xff000000;
439 insn |= (temp >> 8) & 0xffffff;
440 extension = (temp & 0xff) << 16;
441
442 status = (*info->read_memory_func) (memaddr + 5, buffer, 2, info);
443 if (status != 0)
444 {
445 (*info->memory_error_func) (status, memaddr, info);
446 return;
447 }
448 extension |= bfd_getb16 (buffer);
449 }
450 else if (size == 7)
451 {
452 unsigned long temp = 0;
453 status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
454 if (status != 0)
455 {
456 (*info->memory_error_func) (status, memaddr, info);
457 return;
458 }
459 temp |= bfd_getl32 (buffer);
460
461 insn &= 0xffff0000;
462 insn |= (temp >> 16) & 0xffff;
463 extension = (temp & 0xffff) << 8;
464
465 status = (*info->read_memory_func) (memaddr + 6, buffer, 1, info);
466 if (status != 0)
467 {
468 (*info->memory_error_func) (status, memaddr, info);
469 return;
470 }
471 extension |= *(unsigned char *)buffer;
472 }
473
474 match = 1;
475 (*info->fprintf_func) (info->stream, "%s\t", op->name);
476
477 /* Now print the operands. */
478 for (opindex_ptr = op->operands, nocomma = 1;
479 *opindex_ptr != 0;
480 opindex_ptr++)
481 {
482 unsigned long value;
483
484 operand = &mn10300_operands[*opindex_ptr];
485
486 if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
487 {
488 unsigned long temp;
489 value = insn & ((1 << operand->bits) - 1);
490 value <<= (32 - operand->bits);
491 temp = extension >> operand->shift;
492 temp &= ((1 << (32 - operand->bits)) - 1);
493 value |= temp;
494 }
495 /* start-sanitize-am33 */
496 else if ((operand->flags & MN10300_OPERAND_24BIT) != 0)
497 {
498 unsigned long temp;
499 value = insn & ((1 << operand->bits) - 1);
500 value <<= (24 - operand->bits);
501 temp = extension >> operand->shift;
502 temp &= ((1 << (24 - operand->bits)) - 1);
503 value |= temp;
504 if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
505 value = ((value & 0xffffff) ^ (~0x7fffff)) + 0x800000;
506 }
507 /* end-sanitize-am33 */
508 else if ((operand->flags & MN10300_OPERAND_EXTENDED) != 0)
509 {
510 value = ((extension >> (operand->shift))
511 & ((1 << operand->bits) - 1));
512 }
513 else
514 {
515 value = ((insn >> (operand->shift))
516 & ((1 << operand->bits) - 1));
517 }
518
519 if ((operand->flags & MN10300_OPERAND_SIGNED) != 0
520 /* start-sanitize-am33 */
521 /* These are properly extended by the code above. */
522 && ((operand->flags & MN10300_OPERAND_24BIT) == 0)
523 /* end-sanitize-am33 */
524 )
525 value = ((long)(value << (32 - operand->bits))
526 >> (32 - operand->bits));
527
528 if (!nocomma
529 && (!paren
530 || ((operand->flags & MN10300_OPERAND_PAREN) == 0)))
531 (*info->fprintf_func) (info->stream, ",");
532
533 nocomma = 0;
534
535 if ((operand->flags & MN10300_OPERAND_DREG) != 0)
536 {
537 value = ((insn >> (operand->shift + extra_shift))
538 & ((1 << operand->bits) - 1));
539 (*info->fprintf_func) (info->stream, "d%d", value);
540 }
541
542 else if ((operand->flags & MN10300_OPERAND_AREG) != 0)
543 {
544 value = ((insn >> (operand->shift + extra_shift))
545 & ((1 << operand->bits) - 1));
546 (*info->fprintf_func) (info->stream, "a%d", value);
547 }
548
549 else if ((operand->flags & MN10300_OPERAND_SP) != 0)
550 (*info->fprintf_func) (info->stream, "sp");
551
552 else if ((operand->flags & MN10300_OPERAND_PSW) != 0)
553 (*info->fprintf_func) (info->stream, "psw");
554
555 else if ((operand->flags & MN10300_OPERAND_MDR) != 0)
556 (*info->fprintf_func) (info->stream, "mdr");
557
558 /* start-sanitize-am33 */
559 else if ((operand->flags & MN10300_OPERAND_RREG) != 0)
560 {
561 value = ((insn >> (operand->shift + extra_shift))
562 & ((1 << operand->bits) - 1));
563 (*info->fprintf_func) (info->stream, "r%d", value);
564 }
565
566 else if ((operand->flags & MN10300_OPERAND_XRREG) != 0)
567 {
568 value = ((insn >> (operand->shift + extra_shift))
569 & ((1 << operand->bits) - 1));
570 (*info->fprintf_func) (info->stream, "xr%d", value);
571 }
572
573 else if ((operand->flags & MN10300_OPERAND_USP) != 0)
574 (*info->fprintf_func) (info->stream, "usp");
575
576 else if ((operand->flags & MN10300_OPERAND_SSP) != 0)
577 (*info->fprintf_func) (info->stream, "ssp");
578
579 else if ((operand->flags & MN10300_OPERAND_MSP) != 0)
580 (*info->fprintf_func) (info->stream, "msp");
581
582 else if ((operand->flags & MN10300_OPERAND_PC) != 0)
583 (*info->fprintf_func) (info->stream, "pc");
584
585 else if ((operand->flags & MN10300_OPERAND_EPSW) != 0)
586 (*info->fprintf_func) (info->stream, "epsw");
587
588 else if ((operand->flags & MN10300_OPERAND_PLUS) != 0)
589 (*info->fprintf_func) (info->stream, "+");
590 /* end-sanitize-am33 */
591
592 else if ((operand->flags & MN10300_OPERAND_PAREN) != 0)
593 {
594 if (paren)
595 (*info->fprintf_func) (info->stream, ")");
596 else
597 {
598 (*info->fprintf_func) (info->stream, "(");
599 nocomma = 1;
600 }
601 paren = !paren;
602 }
603
604 else if ((operand->flags & MN10300_OPERAND_PCREL) != 0)
605 (*info->print_address_func) ((long) value + memaddr, info);
606
607 else if ((operand->flags & MN10300_OPERAND_MEMADDR) != 0)
608 (*info->print_address_func) (value, info);
609
610 else if ((operand->flags & MN10300_OPERAND_REG_LIST) != 0)
611 {
612 int comma = 0;
613
614 (*info->fprintf_func) (info->stream, "[");
615 if (value & 0x80)
616 {
617 (*info->fprintf_func) (info->stream, "d2");
618 comma = 1;
619 }
620
621 if (value & 0x40)
622 {
623 if (comma)
624 (*info->fprintf_func) (info->stream, ",");
625 (*info->fprintf_func) (info->stream, "d3");
626 comma = 1;
627 }
628
629 if (value & 0x20)
630 {
631 if (comma)
632 (*info->fprintf_func) (info->stream, ",");
633 (*info->fprintf_func) (info->stream, "a2");
634 comma = 1;
635 }
636
637 if (value & 0x10)
638 {
639 if (comma)
640 (*info->fprintf_func) (info->stream, ",");
641 (*info->fprintf_func) (info->stream, "a3");
642 comma = 1;
643 }
644
645 if (value & 0x08)
646 {
647 if (comma)
648 (*info->fprintf_func) (info->stream, ",");
649 (*info->fprintf_func) (info->stream, "other");
650 comma = 1;
651 }
652
653 /* start-sanitize-am33 */
654 if (value & 0x04)
655 {
656 if (comma)
657 (*info->fprintf_func) (info->stream, ",");
658 (*info->fprintf_func) (info->stream, "exreg0");
659 comma = 1;
660 }
661 if (value & 0x02)
662 {
663 if (comma)
664 (*info->fprintf_func) (info->stream, ",");
665 (*info->fprintf_func) (info->stream, "exreg1");
666 comma = 1;
667 }
668 if (value & 0x01)
669 {
670 if (comma)
671 (*info->fprintf_func) (info->stream, ",");
672 (*info->fprintf_func) (info->stream, "exother");
673 comma = 1;
674 }
675 /* end-sanitize-am33 */
676 (*info->fprintf_func) (info->stream, "]");
677 }
678
679 else
680 (*info->fprintf_func) (info->stream, "%d", value);
681 }
682 /* All done. */
683 break;
684 }
685 op++;
686 }
687
688 if (!match)
689 {
690 /* xgettext:c-format */
691 (*info->fprintf_func) (info->stream, _("unknown\t0x%04x"), insn);
692 }
693 }
This page took 0.060593 seconds and 5 git commands to generate.