s12z-dis.c revision 1.1.1.1 1 /* s12z-dis.c -- Freescale S12Z disassembly
2 Copyright (C) 2018 Free Software Foundation, Inc.
3
4 This file is part of the GNU opcodes library.
5
6 This library is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10
11 It is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
20
21 #include "sysdep.h"
22 #include <stdio.h>
23 #include <stdint.h>
24 #include <stdbool.h>
25 #include <assert.h>
26
27 #include "s12z.h"
28
29 #include "bfd.h"
30 #include "dis-asm.h"
31
32
33 #include "disassemble.h"
34
35 static int
36 read_memory (bfd_vma memaddr, bfd_byte* buffer, int size,
37 struct disassemble_info* info)
38 {
39 int status = (*info->read_memory_func) (memaddr, buffer, size, info);
40 if (status != 0)
41 {
42 (*info->memory_error_func) (status, memaddr, info);
43 return -1;
44 }
45 return 0;
46 }
47
48 typedef int (* insn_bytes_f) (bfd_vma memaddr,
49 struct disassemble_info* info);
50
51 typedef void (*operands_f) (bfd_vma memaddr, struct disassemble_info* info);
52
53 enum OPR_MODE
54 {
55 OPR_IMMe4,
56 OPR_REG,
57 OPR_OFXYS,
58 OPR_XY_PRE_INC,
59 OPR_XY_POST_INC,
60 OPR_XY_PRE_DEC,
61 OPR_XY_POST_DEC,
62 OPR_S_PRE_DEC,
63 OPR_S_POST_INC,
64 OPR_REG_DIRECT,
65 OPR_REG_INDIRECT,
66 OPR_IDX_DIRECT,
67 OPR_IDX_INDIRECT,
68 OPR_EXT1,
69 OPR_IDX2_REG,
70 OPR_IDX3_DIRECT,
71 OPR_IDX3_INDIRECT,
72
73 OPR_EXT18,
74 OPR_IDX3_DIRECT_REG,
75 OPR_EXT3_DIRECT,
76 OPR_EXT3_INDIRECT
77 };
78
79 struct opr_pb
80 {
81 uint8_t mask;
82 uint8_t value;
83 int n_operands;
84 enum OPR_MODE mode;
85 };
86
87 static const struct opr_pb opr_pb[] = {
88 {0xF0, 0x70, 1, OPR_IMMe4},
89 {0xF8, 0xB8, 1, OPR_REG},
90 {0xC0, 0x40, 1, OPR_OFXYS},
91 {0xEF, 0xE3, 1, OPR_XY_PRE_INC},
92 {0xEF, 0xE7, 1, OPR_XY_POST_INC},
93 {0xEF, 0xC3, 1, OPR_XY_PRE_DEC},
94 {0xEF, 0xC7, 1, OPR_XY_POST_DEC},
95 {0xFF, 0xFB, 1, OPR_S_PRE_DEC},
96 {0xFF, 0xFF, 1, OPR_S_POST_INC},
97 {0xC8, 0x88, 1, OPR_REG_DIRECT},
98 {0xE8, 0xC8, 1, OPR_REG_INDIRECT},
99
100 {0xCE, 0xC0, 2, OPR_IDX_DIRECT},
101 {0xCE, 0xC4, 2, OPR_IDX_INDIRECT},
102 {0xC0, 0x00, 2, OPR_EXT1},
103
104 {0xC8, 0x80, 3, OPR_IDX2_REG},
105 {0xFA, 0xF8, 3, OPR_EXT18},
106
107 {0xCF, 0xC2, 4, OPR_IDX3_DIRECT},
108 {0xCF, 0xC6, 4, OPR_IDX3_INDIRECT},
109
110 {0xF8, 0xE8, 4, OPR_IDX3_DIRECT_REG},
111 {0xFF, 0xFA, 4, OPR_EXT3_DIRECT},
112 {0xFF, 0xFE, 4, OPR_EXT3_INDIRECT},
113 };
114
115
116 /* Return the number of bytes in a OPR operand, including the XB postbyte.
117 It does not include any preceeding opcodes. */
118 static int
119 opr_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
120 {
121 bfd_byte xb;
122 int status = read_memory (memaddr, &xb, 1, info);
123 if (status < 0)
124 return status;
125
126 size_t i;
127 for (i = 0; i < sizeof (opr_pb) / sizeof (opr_pb[0]); ++i)
128 {
129 const struct opr_pb *pb = opr_pb + i;
130 if ((xb & pb->mask) == pb->value)
131 {
132 return pb->n_operands;
133 }
134 }
135
136 return 1;
137 }
138
139 static int
140 opr_n_bytes_p1 (bfd_vma memaddr, struct disassemble_info* info)
141 {
142 return 1 + opr_n_bytes (memaddr, info);
143 }
144
145 static int
146 opr_n_bytes2 (bfd_vma memaddr, struct disassemble_info* info)
147 {
148 int s = opr_n_bytes (memaddr, info);
149 s += opr_n_bytes (memaddr + s, info);
150 return s + 1;
151 }
152
153 enum BB_MODE
154 {
155 BB_REG_REG_REG,
156 BB_REG_REG_IMM,
157 BB_REG_OPR_REG,
158 BB_OPR_REG_REG,
159 BB_REG_OPR_IMM,
160 BB_OPR_REG_IMM
161 };
162
163 struct opr_bb
164 {
165 uint8_t mask;
166 uint8_t value;
167 int n_operands;
168 bool opr;
169 enum BB_MODE mode;
170 };
171
172 static const struct opr_bb bb_modes[] =
173 {
174 {0x60, 0x00, 2, false, BB_REG_REG_REG},
175 {0x60, 0x20, 3, false, BB_REG_REG_IMM},
176 {0x70, 0x40, 2, true, BB_REG_OPR_REG},
177 {0x70, 0x50, 2, true, BB_OPR_REG_REG},
178 {0x70, 0x60, 3, true, BB_REG_OPR_IMM},
179 {0x70, 0x70, 3, true, BB_OPR_REG_IMM}
180 };
181
182 static int
183 bfextins_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
184 {
185 bfd_byte bb;
186 int status = read_memory (memaddr, &bb, 1, info);
187 if (status < 0)
188 return status;
189
190 size_t i;
191 const struct opr_bb *bbs = 0;
192 for (i = 0; i < sizeof (bb_modes) / sizeof (bb_modes[0]); ++i)
193 {
194 bbs = bb_modes + i;
195 if ((bb & bbs->mask) == bbs->value)
196 {
197 break;
198 }
199 }
200
201 int n = bbs->n_operands;
202 if (bbs->opr)
203 n += opr_n_bytes (memaddr + n - 1, info);
204
205 return n;
206 }
207
208 static int
209 single (bfd_vma memaddr ATTRIBUTE_UNUSED,
210 struct disassemble_info* info ATTRIBUTE_UNUSED)
211 {
212 return 1;
213 }
214
215 static int
216 two (bfd_vma memaddr ATTRIBUTE_UNUSED,
217 struct disassemble_info* info ATTRIBUTE_UNUSED)
218 {
219 return 2;
220 }
221
222 static int
223 three (bfd_vma memaddr ATTRIBUTE_UNUSED,
224 struct disassemble_info* info ATTRIBUTE_UNUSED)
225 {
226 return 3;
227 }
228
229 static int
230 four (bfd_vma memaddr ATTRIBUTE_UNUSED,
231 struct disassemble_info* info ATTRIBUTE_UNUSED)
232 {
233 return 4;
234 }
235
236 static int
237 five (bfd_vma memaddr ATTRIBUTE_UNUSED,
238 struct disassemble_info* info ATTRIBUTE_UNUSED)
239 {
240 return 5;
241 }
242
243 static int
244 pcrel_15bit (bfd_vma memaddr, struct disassemble_info* info)
245 {
246 bfd_byte byte;
247 int status = read_memory (memaddr, &byte, 1, info);
248 if (status < 0)
249 return status;
250 return (byte & 0x80) ? 3 : 2;
251 }
252
253
254
255
257 static void
258 operand_separator (struct disassemble_info *info)
259 {
260 if ((info->flags & 0x2))
261 {
262 (*info->fprintf_func) (info->stream, ", ");
263 }
264 else
265 {
266 (*info->fprintf_func) (info->stream, " ");
267 }
268
269 info->flags |= 0x2;
270 }
271
272
273
275 static void
276 imm1 (bfd_vma memaddr, struct disassemble_info* info)
277 {
278 bfd_byte byte;
279 int status = read_memory (memaddr, &byte, 1, info);
280 if (status < 0)
281 return;
282
283 operand_separator (info);
284 (*info->fprintf_func) (info->stream, "#%d", byte);
285 }
286
287 static void
288 trap_decode (bfd_vma memaddr, struct disassemble_info* info)
289 {
290 imm1 (memaddr - 1, info);
291 }
292
293
294 const struct reg registers[S12Z_N_REGISTERS] =
295 {
296 {"d2", 2},
297 {"d3", 2},
298 {"d4", 2},
299 {"d5", 2},
300
301 {"d0", 1},
302 {"d1", 1},
303
304 {"d6", 4},
305 {"d7", 4},
306
307 {"x", 3},
308 {"y", 3},
309 {"s", 3},
310 {"p", 3},
311 {"cch", 1},
312 {"ccl", 1},
313 {"ccw", 2}
314 };
315
316 static char *
317 xys_from_postbyte (uint8_t postbyte)
318 {
319 char *reg = "?";
320 switch ((postbyte & 0x30) >> 4)
321 {
322 case 0:
323 reg = "x";
324 break;
325 case 1:
326 reg = "y";
327 break;
328 case 2:
329 reg = "s";
330 break;
331 default:
332 reg = "?";
333 break;
334 }
335 return reg;
336 }
337
338 static char *
339 xysp_from_postbyte (uint8_t postbyte)
340 {
341 char *reg = "?";
342 switch ((postbyte & 0x30) >> 4)
343 {
344 case 0:
345 reg = "x";
346 break;
347 case 1:
348 reg = "y";
349 break;
350 case 2:
351 reg = "s";
352 break;
353 default:
354 reg = "p";
355 break;
356 }
357 return reg;
358 }
359
360 /* Render the symbol name whose value is ADDR or the adddress itself if there is
361 no symbol. */
362 static void
363 decode_possible_symbol (bfd_vma addr, struct disassemble_info *info)
364 {
365 if (!info->symbol_at_address_func (addr, info))
366 {
367 (*info->fprintf_func) (info->stream, "%" BFD_VMA_FMT "d", addr);
368 }
369 else
370 {
371 asymbol *sym = NULL;
372 int j;
373 for (j = 0; j < info->symtab_size; ++j)
374 {
375 sym = info->symtab[j];
376 if (bfd_asymbol_value (sym) == addr)
377 {
378 break;
379 }
380 }
381 if (j < info->symtab_size)
382 (*info->fprintf_func) (info->stream, "%s", bfd_asymbol_name (sym));
383 }
384 }
385
386 static void ld_18bit_decode (bfd_vma memaddr, struct disassemble_info* info);
387
388 static void
389 ext24_decode (bfd_vma memaddr, struct disassemble_info* info)
390 {
391 uint8_t buffer[3];
392 int status = read_memory (memaddr, buffer, 3, info);
393 if (status < 0)
394 return;
395
396 int i;
397 uint32_t addr = 0;
398 for (i = 0; i < 3; ++i)
399 {
400 addr <<= 8;
401 addr |= buffer[i];
402 }
403
404 operand_separator (info);
405 decode_possible_symbol (addr, info);
406 }
407
408
409 static uint32_t
410 decode_signed_value (bfd_vma memaddr, struct disassemble_info* info, short size)
411 {
412 assert (size >0);
413 assert (size <= 4);
414 bfd_byte buffer[4];
415 if (0 > read_memory (memaddr, buffer, size, info))
416 {
417 return 0;
418 }
419
420 int i;
421 uint32_t value = 0;
422 for (i = 0; i < size; ++i)
423 {
424 value |= buffer[i] << (8 * (size - i - 1));
425 }
426
427 if (buffer[0] & 0x80)
428 {
429 /* Deal with negative values */
430 value -= 0x1UL << (size * 8);
431 }
432 return value;
433 }
434
435
436 static void
437 opr_decode (bfd_vma memaddr, struct disassemble_info* info)
438 {
439 bfd_byte postbyte;
440 int status = read_memory (memaddr, &postbyte, 1, info);
441 if (status < 0)
442 return;
443
444 enum OPR_MODE mode = -1;
445 size_t i;
446 for (i = 0; i < sizeof (opr_pb) / sizeof (opr_pb[0]); ++i)
447 {
448 const struct opr_pb *pb = opr_pb + i;
449 if ((postbyte & pb->mask) == pb->value)
450 {
451 mode = pb->mode;
452 break;
453 }
454 }
455
456 operand_separator (info);
457 switch (mode)
458 {
459 case OPR_IMMe4:
460 {
461 int n;
462 uint8_t x = (postbyte & 0x0F);
463 if (x == 0)
464 n = -1;
465 else
466 n = x;
467
468 (*info->fprintf_func) (info->stream, "#%d", n);
469 break;
470 }
471 case OPR_REG:
472 {
473 uint8_t x = (postbyte & 0x07);
474 (*info->fprintf_func) (info->stream, "%s", registers[x].name);
475 break;
476 }
477 case OPR_OFXYS:
478 {
479 const char *reg = xys_from_postbyte (postbyte);
480 (*info->fprintf_func) (info->stream, "(%d,%s)", postbyte & 0x0F, reg);
481 break;
482 }
483 case OPR_REG_DIRECT:
484 {
485 (*info->fprintf_func) (info->stream, "(%s,%s)", registers[postbyte & 0x07].name,
486 xys_from_postbyte (postbyte));
487 break;
488 }
489 case OPR_REG_INDIRECT:
490 {
491 (*info->fprintf_func) (info->stream, "[%s,%s]", registers[postbyte & 0x07].name,
492 (postbyte & 0x10) ? "y": "x");
493 break;
494 }
495
496 case OPR_IDX_INDIRECT:
497 {
498 uint8_t x1;
499 read_memory (memaddr + 1, &x1, 1, info);
500 int idx = x1;
501
502 if (postbyte & 0x01)
503 {
504 /* Deal with negative values */
505 idx -= 0x1UL << 8;
506 }
507
508 (*info->fprintf_func) (info->stream, "[%d,%s]", idx,
509 xysp_from_postbyte (postbyte));
510 break;
511 }
512
513 case OPR_IDX3_DIRECT:
514 {
515 uint8_t x[3];
516 read_memory (memaddr + 1, x, 3, info);
517 int idx = x[0] << 16 | x[1] << 8 | x[2];
518
519 if (x[0] & 0x80)
520 {
521 /* Deal with negative values */
522 idx -= 0x1UL << 24;
523 }
524
525 (*info->fprintf_func) (info->stream, "(%d,%s)", idx,
526 xysp_from_postbyte (postbyte));
527 break;
528 }
529
530 case OPR_IDX3_DIRECT_REG:
531 {
532 uint8_t x[3];
533 read_memory (memaddr + 1, x, 3, info);
534 int idx = x[0] << 16 | x[1] << 8 | x[2];
535
536 if (x[0] & 0x80)
537 {
538 /* Deal with negative values */
539 idx -= 0x1UL << 24;
540 }
541
542 (*info->fprintf_func) (info->stream, "(%d,%s)", idx,
543 registers[postbyte & 0x07].name);
544 break;
545 }
546
547 case OPR_IDX3_INDIRECT:
548 {
549 uint8_t x[3];
550 read_memory (memaddr + 1, x, 3, info);
551 int idx = x[0] << 16 | x[1] << 8 | x[2];
552
553 if (x[0] & 0x80)
554 {
555 /* Deal with negative values */
556 idx -= 0x1UL << 24;
557 }
558
559 (*info->fprintf_func) (info->stream, "[%d,%s]", idx,
560 xysp_from_postbyte (postbyte));
561 break;
562 }
563
564 case OPR_IDX_DIRECT:
565 {
566 uint8_t x1;
567 read_memory (memaddr + 1, &x1, 1, info);
568 int idx = x1;
569
570 if (postbyte & 0x01)
571 {
572 /* Deal with negative values */
573 idx -= 0x1UL << 8;
574 }
575
576 (*info->fprintf_func) (info->stream, "(%d,%s)", idx,
577 xysp_from_postbyte (postbyte));
578 break;
579 }
580
581 case OPR_IDX2_REG:
582 {
583 uint8_t x[2];
584 read_memory (memaddr + 1, x, 2, info);
585 uint32_t offset = x[1] | x[0] << 8 ;
586 offset |= (postbyte & 0x30) << 12;
587
588 (*info->fprintf_func) (info->stream, "(%d,%s)", offset,
589 registers[postbyte & 0x07].name);
590 break;
591 }
592
593 case OPR_XY_PRE_INC:
594 {
595 (*info->fprintf_func) (info->stream, "(+%s)",
596 (postbyte & 0x10) ? "y": "x");
597
598 break;
599 }
600 case OPR_XY_POST_INC:
601 {
602 (*info->fprintf_func) (info->stream, "(%s+)",
603 (postbyte & 0x10) ? "y": "x");
604
605 break;
606 }
607 case OPR_XY_PRE_DEC:
608 {
609 (*info->fprintf_func) (info->stream, "(-%s)",
610 (postbyte & 0x10) ? "y": "x");
611
612 break;
613 }
614 case OPR_XY_POST_DEC:
615 {
616 (*info->fprintf_func) (info->stream, "(%s-)",
617 (postbyte & 0x10) ? "y": "x");
618
619 break;
620 }
621 case OPR_S_PRE_DEC:
622 {
623 (*info->fprintf_func) (info->stream, "(-s)");
624 break;
625 }
626 case OPR_S_POST_INC:
627 {
628 (*info->fprintf_func) (info->stream, "(s+)");
629 break;
630 }
631
632 case OPR_EXT18:
633 {
634 const size_t size = 2;
635 bfd_byte buffer[4];
636 status = read_memory (memaddr + 1, buffer, size, info);
637 if (status < 0)
638 return;
639
640 uint32_t ext18 = 0;
641 for (i = 0; i < size; ++i)
642 {
643 ext18 <<= 8;
644 ext18 |= buffer[i];
645 }
646
647 ext18 |= (postbyte & 0x01) << 16;
648 ext18 |= (postbyte & 0x04) << 15;
649
650 decode_possible_symbol (ext18, info);
651 break;
652 }
653
654 case OPR_EXT1:
655 {
656 uint8_t x1 = 0;
657 read_memory (memaddr + 1, &x1, 1, info);
658 int16_t addr;
659 addr = x1;
660 addr |= (postbyte & 0x3f) << 8;
661
662 decode_possible_symbol (addr, info);
663 break;
664 }
665
666 case OPR_EXT3_DIRECT:
667 {
668 const size_t size = 3;
669 bfd_byte buffer[4];
670 status = read_memory (memaddr + 1, buffer, size, info);
671 if (status < 0)
672 return;
673
674 uint32_t ext24 = 0;
675 for (i = 0; i < size; ++i)
676 {
677 ext24 |= buffer[i] << (8 * (size - i - 1));
678 }
679
680 decode_possible_symbol (ext24, info);
681 break;
682 }
683
684 case OPR_EXT3_INDIRECT:
685 {
686 const size_t size = 3;
687 bfd_byte buffer[4];
688 status = read_memory (memaddr + 1, buffer, size, info);
689 if (status < 0)
690 return;
691
692 uint32_t ext24 = 0;
693 for (i = 0; i < size; ++i)
694 {
695 ext24 |= buffer[i] << (8 * (size - i - 1));
696 }
697
698 (*info->fprintf_func) (info->stream, "[%d]", ext24);
699
700 break;
701 }
702
703 default:
704 (*info->fprintf_func) (info->stream, "Unknown OPR mode #0x%x (%d)", postbyte, mode);
705 }
706 }
707
708
709 static void
710 opr_decode2 (bfd_vma memaddr, struct disassemble_info* info)
711 {
712 int n = opr_n_bytes (memaddr, info);
713 opr_decode (memaddr, info);
714 opr_decode (memaddr + n, info);
715 }
716
717 static void
718 imm1234 (bfd_vma memaddr, struct disassemble_info* info, int base)
719 {
720 bfd_byte opcode;
721 int status = read_memory (memaddr - 1, &opcode, 1, info);
722 if (status < 0)
723 return;
724
725 opcode -= base;
726
727 int size = registers[opcode & 0xF].bytes;
728
729 uint32_t imm = decode_signed_value (memaddr, info, size);
730 operand_separator (info);
731 (*info->fprintf_func) (info->stream, "#%d", imm);
732 }
733
734
735 /* Special case of LD and CMP with register S and IMM operand */
736 static void
737 reg_s_imm (bfd_vma memaddr, struct disassemble_info* info)
738 {
739 operand_separator (info);
740 (*info->fprintf_func) (info->stream, "s");
741
742 uint32_t imm = decode_signed_value (memaddr, info, 3);
743 operand_separator (info);
744 (*info->fprintf_func) (info->stream, "#%d", imm);
745 }
746
747 /* Special case of LD, CMP and ST with register S and OPR operand */
748 static void
749 reg_s_opr (bfd_vma memaddr, struct disassemble_info* info)
750 {
751 operand_separator (info);
752 (*info->fprintf_func) (info->stream, "s");
753
754 opr_decode (memaddr, info);
755 }
756
757 static void
758 imm1234_8base (bfd_vma memaddr, struct disassemble_info* info)
759 {
760 imm1234 (memaddr, info, 8);
761 }
762
763 static void
764 imm1234_0base (bfd_vma memaddr, struct disassemble_info* info)
765 {
766 imm1234 (memaddr, info, 0);
767 }
768
769 static void
770 tfr (bfd_vma memaddr, struct disassemble_info* info)
771 {
772 bfd_byte byte;
773 int status = read_memory (memaddr, &byte, 1, info);
774 if (status < 0)
775 return;
776
777 operand_separator (info);
778 (*info->fprintf_func) (info->stream, "%s, %s",
779 registers[byte >> 4].name,
780 registers[byte & 0xF].name);
781 }
782
783
784 static void
785 reg (bfd_vma memaddr, struct disassemble_info* info)
786 {
787 bfd_byte byte;
788 int status = read_memory (memaddr - 1, &byte, 1, info);
789 if (status < 0)
790 return;
791
792 operand_separator (info);
793 (*info->fprintf_func) (info->stream, "%s", registers[byte & 0x07].name);
794 }
795
796 static void
797 reg_xy (bfd_vma memaddr, struct disassemble_info* info)
798 {
799 bfd_byte byte;
800 int status = read_memory (memaddr - 1, &byte, 1, info);
801 if (status < 0)
802 return;
803
804 operand_separator (info);
805 (*info->fprintf_func) (info->stream, "%s", (byte & 0x01) ? "y" : "x");
806 }
807
808 static void
809 lea_reg_xys_opr (bfd_vma memaddr, struct disassemble_info* info)
810 {
811 bfd_byte byte;
812 int status = read_memory (memaddr - 1, &byte, 1, info);
813 if (status < 0)
814 return;
815
816 char *reg = NULL;
817 switch (byte & 0x03)
818 {
819 case 0x00:
820 reg = "x";
821 break;
822 case 0x01:
823 reg = "y";
824 break;
825 case 0x02:
826 reg = "s";
827 break;
828 }
829
830 operand_separator (info);
831 (*info->fprintf_func) (info->stream, "%s", reg);
832 opr_decode (memaddr, info);
833 }
834
835
836
837 static void
838 lea_reg_xys (bfd_vma memaddr, struct disassemble_info* info)
839 {
840 bfd_byte byte;
841 int status = read_memory (memaddr - 1, &byte, 1, info);
842 if (status < 0)
843 return;
844
845 char *reg = NULL;
846 switch (byte & 0x03)
847 {
848 case 0x00:
849 reg = "x";
850 break;
851 case 0x01:
852 reg = "y";
853 break;
854 case 0x02:
855 reg = "s";
856 break;
857 }
858
859 status = read_memory (memaddr, &byte, 1, info);
860 if (status < 0)
861 return;
862
863 int8_t v = byte;
864
865 operand_separator (info);
866 (*info->fprintf_func) (info->stream, "%s, (%d,%s)", reg, v, reg);
867 }
868
869
870 /* PC Relative offsets of size 15 or 7 bits */
871 static void
872 rel_15_7 (bfd_vma memaddr, struct disassemble_info* info, int offset)
873 {
874 bfd_byte upper;
875 int status = read_memory (memaddr, &upper, 1, info);
876 if (status < 0)
877 return;
878
879 bool rel_size = (upper & 0x80);
880
881 int16_t addr = upper;
882 if (rel_size)
883 {
884 /* 15 bits. Get the next byte */
885 bfd_byte lower;
886 status = read_memory (memaddr + 1, &lower, 1, info);
887 if (status < 0)
888 return;
889
890 addr <<= 8;
891 addr |= lower;
892 addr &= 0x7FFF;
893
894 bool negative = (addr & 0x4000);
895 addr &= 0x3FFF;
896 if (negative)
897 addr = addr - 0x4000;
898 }
899 else
900 {
901 /* 7 bits. */
902 bool negative = (addr & 0x40);
903 addr &= 0x3F;
904 if (negative)
905 addr = addr - 0x40;
906 }
907
908 operand_separator (info);
909 if (!info->symbol_at_address_func (addr + memaddr - offset, info))
910 {
911 (*info->fprintf_func) (info->stream, "*%+d", addr);
912 }
913 else
914 {
915 asymbol *sym = NULL;
916 int i;
917 for (i = 0; i < info->symtab_size; ++i)
918 {
919 sym = info->symtab[i];
920 if (bfd_asymbol_value (sym) == addr + memaddr - offset)
921 {
922 break;
923 }
924 }
925 if (i < info->symtab_size)
926 (*info->fprintf_func) (info->stream, "%s", bfd_asymbol_name (sym));
927 }
928 }
929
930
931 /* PC Relative offsets of size 15 or 7 bits */
932 static void
933 decode_rel_15_7 (bfd_vma memaddr, struct disassemble_info* info)
934 {
935 rel_15_7 (memaddr, info, 1);
936 }
937
938 struct opcode
939 {
940 const char *mnemonic;
941 insn_bytes_f insn_bytes;
942 operands_f operands;
943 operands_f operands2;
944 };
945
946 static int shift_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
947 static int mov_imm_opr_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
948 static int loop_prim_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
949 static void mov_imm_opr (bfd_vma memaddr, struct disassemble_info* info);
950 static void bm_rel_decode (bfd_vma memaddr, struct disassemble_info* info);
951 static int bm_rel_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
952 static int mul_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
953 static void mul_decode (bfd_vma memaddr, struct disassemble_info* info);
954 static int bm_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
955 static void bm_decode (bfd_vma memaddr, struct disassemble_info* info);
956
957 static void
958 cmp_xy (bfd_vma memaddr ATTRIBUTE_UNUSED, struct disassemble_info* info)
959 {
960 operand_separator (info);
961 (*info->fprintf_func) (info->stream, "x, y");
962 }
963
964 static void
965 sub_d6_x_y (bfd_vma memaddr ATTRIBUTE_UNUSED, struct disassemble_info* info)
966 {
967 operand_separator (info);
968 (*info->fprintf_func) (info->stream, "d6, x, y");
969 }
970
971 static void
972 sub_d6_y_x (bfd_vma memaddr ATTRIBUTE_UNUSED, struct disassemble_info* info)
973 {
974 operand_separator (info);
975 (*info->fprintf_func) (info->stream, "d6, y, x");
976 }
977
978 static const char shift_size_table[] = {
979 'b', 'w', 'p', 'l'
980 };
981
982 static const struct opcode page2[] =
983 {
984 [0x00] = {"ld", opr_n_bytes_p1, 0, reg_s_opr},
985 [0x01] = {"st", opr_n_bytes_p1, 0, reg_s_opr},
986 [0x02] = {"cmp", opr_n_bytes_p1, 0, reg_s_opr},
987 [0x03] = {"ld", four, 0, reg_s_imm},
988 [0x04] = {"cmp", four, 0, reg_s_imm},
989 [0x05] = {"stop", single, 0, 0},
990 [0x06] = {"wai", single, 0, 0},
991 [0x07] = {"sys", single, 0, 0},
992 [0x08] = {NULL, bfextins_n_bytes, 0, 0}, /* BFEXT / BFINS */
993 [0x09] = {NULL, bfextins_n_bytes, 0, 0},
994 [0x0a] = {NULL, bfextins_n_bytes, 0, 0},
995 [0x0b] = {NULL, bfextins_n_bytes, 0, 0},
996 [0x0c] = {NULL, bfextins_n_bytes, 0, 0},
997 [0x0d] = {NULL, bfextins_n_bytes, 0, 0},
998 [0x0e] = {NULL, bfextins_n_bytes, 0, 0},
999 [0x0f] = {NULL, bfextins_n_bytes, 0, 0},
1000 [0x10] = {"minu", opr_n_bytes_p1, reg, opr_decode},
1001 [0x11] = {"minu", opr_n_bytes_p1, reg, opr_decode},
1002 [0x12] = {"minu", opr_n_bytes_p1, reg, opr_decode},
1003 [0x13] = {"minu", opr_n_bytes_p1, reg, opr_decode},
1004 [0x14] = {"minu", opr_n_bytes_p1, reg, opr_decode},
1005 [0x15] = {"minu", opr_n_bytes_p1, reg, opr_decode},
1006 [0x16] = {"minu", opr_n_bytes_p1, reg, opr_decode},
1007 [0x17] = {"minu", opr_n_bytes_p1, reg, opr_decode},
1008 [0x18] = {"maxu", opr_n_bytes_p1, reg, opr_decode},
1009 [0x19] = {"maxu", opr_n_bytes_p1, reg, opr_decode},
1010 [0x1a] = {"maxu", opr_n_bytes_p1, reg, opr_decode},
1011 [0x1b] = {"maxu", opr_n_bytes_p1, reg, opr_decode},
1012 [0x1c] = {"maxu", opr_n_bytes_p1, reg, opr_decode},
1013 [0x1d] = {"maxu", opr_n_bytes_p1, reg, opr_decode},
1014 [0x1e] = {"maxu", opr_n_bytes_p1, reg, opr_decode},
1015 [0x1f] = {"maxu", opr_n_bytes_p1, reg, opr_decode},
1016 [0x20] = {"mins", opr_n_bytes_p1, reg, opr_decode},
1017 [0x21] = {"mins", opr_n_bytes_p1, reg, opr_decode},
1018 [0x22] = {"mins", opr_n_bytes_p1, reg, opr_decode},
1019 [0x23] = {"mins", opr_n_bytes_p1, reg, opr_decode},
1020 [0x24] = {"mins", opr_n_bytes_p1, reg, opr_decode},
1021 [0x25] = {"mins", opr_n_bytes_p1, reg, opr_decode},
1022 [0x26] = {"mins", opr_n_bytes_p1, reg, opr_decode},
1023 [0x27] = {"mins", opr_n_bytes_p1, reg, opr_decode},
1024 [0x28] = {"maxs", opr_n_bytes_p1, reg, opr_decode},
1025 [0x29] = {"maxs", opr_n_bytes_p1, reg, opr_decode},
1026 [0x2a] = {"maxs", opr_n_bytes_p1, reg, opr_decode},
1027 [0x2b] = {"maxs", opr_n_bytes_p1, reg, opr_decode},
1028 [0x2c] = {"maxs", opr_n_bytes_p1, reg, opr_decode},
1029 [0x2d] = {"maxs", opr_n_bytes_p1, reg, opr_decode},
1030 [0x2e] = {"maxs", opr_n_bytes_p1, reg, opr_decode},
1031 [0x2f] = {"maxs", opr_n_bytes_p1, reg, opr_decode},
1032 [0x30] = {"div", mul_n_bytes, mul_decode, 0},
1033 [0x31] = {"div", mul_n_bytes, mul_decode, 0},
1034 [0x32] = {"div", mul_n_bytes, mul_decode, 0},
1035 [0x33] = {"div", mul_n_bytes, mul_decode, 0},
1036 [0x34] = {"div", mul_n_bytes, mul_decode, 0},
1037 [0x35] = {"div", mul_n_bytes, mul_decode, 0},
1038 [0x36] = {"div", mul_n_bytes, mul_decode, 0},
1039 [0x37] = {"div", mul_n_bytes, mul_decode, 0},
1040 [0x38] = {"mod", mul_n_bytes, mul_decode, 0},
1041 [0x39] = {"mod", mul_n_bytes, mul_decode, 0},
1042 [0x3a] = {"mod", mul_n_bytes, mul_decode, 0},
1043 [0x3b] = {"mod", mul_n_bytes, mul_decode, 0},
1044 [0x3c] = {"mod", mul_n_bytes, mul_decode, 0},
1045 [0x3d] = {"mod", mul_n_bytes, mul_decode, 0},
1046 [0x3e] = {"mod", mul_n_bytes, mul_decode, 0},
1047 [0x3f] = {"mod", mul_n_bytes, mul_decode, 0},
1048 [0x40] = {"abs", single, reg, 0},
1049 [0x41] = {"abs", single, reg, 0},
1050 [0x42] = {"abs", single, reg, 0},
1051 [0x43] = {"abs", single, reg, 0},
1052 [0x44] = {"abs", single, reg, 0},
1053 [0x45] = {"abs", single, reg, 0},
1054 [0x46] = {"abs", single, reg, 0},
1055 [0x47] = {"abs", single, reg, 0},
1056 [0x48] = {"mac", mul_n_bytes, mul_decode, 0},
1057 [0x49] = {"mac", mul_n_bytes, mul_decode, 0},
1058 [0x4a] = {"mac", mul_n_bytes, mul_decode, 0},
1059 [0x4b] = {"mac", mul_n_bytes, mul_decode, 0},
1060 [0x4c] = {"mac", mul_n_bytes, mul_decode, 0},
1061 [0x4d] = {"mac", mul_n_bytes, mul_decode, 0},
1062 [0x4e] = {"mac", mul_n_bytes, mul_decode, 0},
1063 [0x4f] = {"mac", mul_n_bytes, mul_decode, 0},
1064 [0x50] = {"adc", three, reg, imm1234_0base},
1065 [0x51] = {"adc", three, reg, imm1234_0base},
1066 [0x52] = {"adc", three, reg, imm1234_0base},
1067 [0x53] = {"adc", three, reg, imm1234_0base},
1068 [0x54] = {"adc", two, reg, imm1234_0base},
1069 [0x55] = {"adc", two, reg, imm1234_0base},
1070 [0x56] = {"adc", five, reg, imm1234_0base},
1071 [0x57] = {"adc", five, reg, imm1234_0base},
1072 [0x58] = {"bit", three, reg, imm1234_8base},
1073 [0x59] = {"bit", three, reg, imm1234_8base},
1074 [0x5a] = {"bit", three, reg, imm1234_8base},
1075 [0x5b] = {"bit", three, reg, imm1234_8base},
1076 [0x5c] = {"bit", two, reg, imm1234_8base},
1077 [0x5d] = {"bit", two, reg, imm1234_8base},
1078 [0x5e] = {"bit", five, reg, imm1234_8base},
1079 [0x5f] = {"bit", five, reg, imm1234_8base},
1080 [0x60] = {"adc", opr_n_bytes_p1, reg, opr_decode},
1081 [0x61] = {"adc", opr_n_bytes_p1, reg, opr_decode},
1082 [0x62] = {"adc", opr_n_bytes_p1, reg, opr_decode},
1083 [0x63] = {"adc", opr_n_bytes_p1, reg, opr_decode},
1084 [0x64] = {"adc", opr_n_bytes_p1, reg, opr_decode},
1085 [0x65] = {"adc", opr_n_bytes_p1, reg, opr_decode},
1086 [0x66] = {"adc", opr_n_bytes_p1, reg, opr_decode},
1087 [0x67] = {"adc", opr_n_bytes_p1, reg, opr_decode},
1088 [0x68] = {"bit", opr_n_bytes_p1, reg, opr_decode},
1089 [0x69] = {"bit", opr_n_bytes_p1, reg, opr_decode},
1090 [0x6a] = {"bit", opr_n_bytes_p1, reg, opr_decode},
1091 [0x6b] = {"bit", opr_n_bytes_p1, reg, opr_decode},
1092 [0x6c] = {"bit", opr_n_bytes_p1, reg, opr_decode},
1093 [0x6d] = {"bit", opr_n_bytes_p1, reg, opr_decode},
1094 [0x6e] = {"bit", opr_n_bytes_p1, reg, opr_decode},
1095 [0x6f] = {"bit", opr_n_bytes_p1, reg, opr_decode},
1096 [0x70] = {"sbc", three, reg, imm1234_0base},
1097 [0x71] = {"sbc", three, reg, imm1234_0base},
1098 [0x72] = {"sbc", three, reg, imm1234_0base},
1099 [0x73] = {"sbc", three, reg, imm1234_0base},
1100 [0x74] = {"sbc", two, reg, imm1234_0base},
1101 [0x75] = {"sbc", two, reg, imm1234_0base},
1102 [0x76] = {"sbc", five, reg, imm1234_0base},
1103 [0x77] = {"sbc", five, reg, imm1234_0base},
1104 [0x78] = {"eor", three, reg, imm1234_8base},
1105 [0x79] = {"eor", three, reg, imm1234_8base},
1106 [0x7a] = {"eor", three, reg, imm1234_8base},
1107 [0x7b] = {"eor", three, reg, imm1234_8base},
1108 [0x7c] = {"eor", two, reg, imm1234_8base},
1109 [0x7d] = {"eor", two, reg, imm1234_8base},
1110 [0x7e] = {"eor", five, reg, imm1234_8base},
1111 [0x7f] = {"eor", five, reg, imm1234_8base},
1112 [0x80] = {"sbc", opr_n_bytes_p1, reg, opr_decode},
1113 [0x81] = {"sbc", opr_n_bytes_p1, reg, opr_decode},
1114 [0x82] = {"sbc", opr_n_bytes_p1, reg, opr_decode},
1115 [0x83] = {"sbc", opr_n_bytes_p1, reg, opr_decode},
1116 [0x84] = {"sbc", opr_n_bytes_p1, reg, opr_decode},
1117 [0x85] = {"sbc", opr_n_bytes_p1, reg, opr_decode},
1118 [0x86] = {"sbc", opr_n_bytes_p1, reg, opr_decode},
1119 [0x87] = {"sbc", opr_n_bytes_p1, reg, opr_decode},
1120 [0x88] = {"eor", opr_n_bytes_p1, reg, opr_decode},
1121 [0x89] = {"eor", opr_n_bytes_p1, reg, opr_decode},
1122 [0x8a] = {"eor", opr_n_bytes_p1, reg, opr_decode},
1123 [0x8b] = {"eor", opr_n_bytes_p1, reg, opr_decode},
1124 [0x8c] = {"eor", opr_n_bytes_p1, reg, opr_decode},
1125 [0x8d] = {"eor", opr_n_bytes_p1, reg, opr_decode},
1126 [0x8e] = {"eor", opr_n_bytes_p1, reg, opr_decode},
1127 [0x8f] = {"eor", opr_n_bytes_p1, reg, opr_decode},
1128 [0x90] = {"rti", single, 0, 0},
1129 [0x91] = {"clb", two, tfr, 0},
1130 [0x92] = {"trap", single, trap_decode, 0},
1131 [0x93] = {"trap", single, trap_decode, 0},
1132 [0x94] = {"trap", single, trap_decode, 0},
1133 [0x95] = {"trap", single, trap_decode, 0},
1134 [0x96] = {"trap", single, trap_decode, 0},
1135 [0x97] = {"trap", single, trap_decode, 0},
1136 [0x98] = {"trap", single, trap_decode, 0},
1137 [0x99] = {"trap", single, trap_decode, 0},
1138 [0x9a] = {"trap", single, trap_decode, 0},
1139 [0x9b] = {"trap", single, trap_decode, 0},
1140 [0x9c] = {"trap", single, trap_decode, 0},
1141 [0x9d] = {"trap", single, trap_decode, 0},
1142 [0x9e] = {"trap", single, trap_decode, 0},
1143 [0x9f] = {"trap", single, trap_decode, 0},
1144 [0xa0] = {"sat", single, reg, 0},
1145 [0xa1] = {"sat", single, reg, 0},
1146 [0xa2] = {"sat", single, reg, 0},
1147 [0xa3] = {"sat", single, reg, 0},
1148 [0xa4] = {"sat", single, reg, 0},
1149 [0xa5] = {"sat", single, reg, 0},
1150 [0xa6] = {"sat", single, reg, 0},
1151 [0xa7] = {"sat", single, reg, 0},
1152 [0xa8] = {"trap", single, trap_decode, 0},
1153 [0xa9] = {"trap", single, trap_decode, 0},
1154 [0xaa] = {"trap", single, trap_decode, 0},
1155 [0xab] = {"trap", single, trap_decode, 0},
1156 [0xac] = {"trap", single, trap_decode, 0},
1157 [0xad] = {"trap", single, trap_decode, 0},
1158 [0xae] = {"trap", single, trap_decode, 0},
1159 [0xaf] = {"trap", single, trap_decode, 0},
1160 [0xb0] = {"qmul", mul_n_bytes, mul_decode, 0},
1161 [0xb1] = {"qmul", mul_n_bytes, mul_decode, 0},
1162 [0xb2] = {"qmul", mul_n_bytes, mul_decode, 0},
1163 [0xb3] = {"qmul", mul_n_bytes, mul_decode, 0},
1164 [0xb4] = {"qmul", mul_n_bytes, mul_decode, 0},
1165 [0xb5] = {"qmul", mul_n_bytes, mul_decode, 0},
1166 [0xb6] = {"qmul", mul_n_bytes, mul_decode, 0},
1167 [0xb7] = {"qmul", mul_n_bytes, mul_decode, 0},
1168 [0xb8] = {"trap", single, trap_decode, 0},
1169 [0xb9] = {"trap", single, trap_decode, 0},
1170 [0xba] = {"trap", single, trap_decode, 0},
1171 [0xbb] = {"trap", single, trap_decode, 0},
1172 [0xbc] = {"trap", single, trap_decode, 0},
1173 [0xbd] = {"trap", single, trap_decode, 0},
1174 [0xbe] = {"trap", single, trap_decode, 0},
1175 [0xbf] = {"trap", single, trap_decode, 0},
1176 [0xc0] = {"trap", single, trap_decode, 0},
1177 [0xc1] = {"trap", single, trap_decode, 0},
1178 [0xc2] = {"trap", single, trap_decode, 0},
1179 [0xc3] = {"trap", single, trap_decode, 0},
1180 [0xc4] = {"trap", single, trap_decode, 0},
1181 [0xc5] = {"trap", single, trap_decode, 0},
1182 [0xc6] = {"trap", single, trap_decode, 0},
1183 [0xc7] = {"trap", single, trap_decode, 0},
1184 [0xc8] = {"trap", single, trap_decode, 0},
1185 [0xc9] = {"trap", single, trap_decode, 0},
1186 [0xca] = {"trap", single, trap_decode, 0},
1187 [0xcb] = {"trap", single, trap_decode, 0},
1188 [0xcc] = {"trap", single, trap_decode, 0},
1189 [0xcd] = {"trap", single, trap_decode, 0},
1190 [0xce] = {"trap", single, trap_decode, 0},
1191 [0xcf] = {"trap", single, trap_decode, 0},
1192 [0xd0] = {"trap", single, trap_decode, 0},
1193 [0xd1] = {"trap", single, trap_decode, 0},
1194 [0xd2] = {"trap", single, trap_decode, 0},
1195 [0xd3] = {"trap", single, trap_decode, 0},
1196 [0xd4] = {"trap", single, trap_decode, 0},
1197 [0xd5] = {"trap", single, trap_decode, 0},
1198 [0xd6] = {"trap", single, trap_decode, 0},
1199 [0xd7] = {"trap", single, trap_decode, 0},
1200 [0xd8] = {"trap", single, trap_decode, 0},
1201 [0xd9] = {"trap", single, trap_decode, 0},
1202 [0xda] = {"trap", single, trap_decode, 0},
1203 [0xdb] = {"trap", single, trap_decode, 0},
1204 [0xdc] = {"trap", single, trap_decode, 0},
1205 [0xdd] = {"trap", single, trap_decode, 0},
1206 [0xde] = {"trap", single, trap_decode, 0},
1207 [0xdf] = {"trap", single, trap_decode, 0},
1208 [0xe0] = {"trap", single, trap_decode, 0},
1209 [0xe1] = {"trap", single, trap_decode, 0},
1210 [0xe2] = {"trap", single, trap_decode, 0},
1211 [0xe3] = {"trap", single, trap_decode, 0},
1212 [0xe4] = {"trap", single, trap_decode, 0},
1213 [0xe5] = {"trap", single, trap_decode, 0},
1214 [0xe6] = {"trap", single, trap_decode, 0},
1215 [0xe7] = {"trap", single, trap_decode, 0},
1216 [0xe8] = {"trap", single, trap_decode, 0},
1217 [0xe9] = {"trap", single, trap_decode, 0},
1218 [0xea] = {"trap", single, trap_decode, 0},
1219 [0xeb] = {"trap", single, trap_decode, 0},
1220 [0xec] = {"trap", single, trap_decode, 0},
1221 [0xed] = {"trap", single, trap_decode, 0},
1222 [0xee] = {"trap", single, trap_decode, 0},
1223 [0xef] = {"trap", single, trap_decode, 0},
1224 [0xf0] = {"trap", single, trap_decode, 0},
1225 [0xf1] = {"trap", single, trap_decode, 0},
1226 [0xf2] = {"trap", single, trap_decode, 0},
1227 [0xf3] = {"trap", single, trap_decode, 0},
1228 [0xf4] = {"trap", single, trap_decode, 0},
1229 [0xf5] = {"trap", single, trap_decode, 0},
1230 [0xf6] = {"trap", single, trap_decode, 0},
1231 [0xf7] = {"trap", single, trap_decode, 0},
1232 [0xf8] = {"trap", single, trap_decode, 0},
1233 [0xf9] = {"trap", single, trap_decode, 0},
1234 [0xfa] = {"trap", single, trap_decode, 0},
1235 [0xfb] = {"trap", single, trap_decode, 0},
1236 [0xfc] = {"trap", single, trap_decode, 0},
1237 [0xfd] = {"trap", single, trap_decode, 0},
1238 [0xfe] = {"trap", single, trap_decode, 0},
1239 [0xff] = {"trap", single, trap_decode, 0},
1240 };
1241
1242 static const struct opcode page1[] =
1243 {
1244 [0x00] = {"bgnd", single, 0, 0},
1245 [0x01] = {"nop", single, 0, 0},
1246 [0x02] = {"brclr", bm_rel_n_bytes, bm_rel_decode, 0},
1247 [0x03] = {"brset", bm_rel_n_bytes, bm_rel_decode, 0},
1248 [0x04] = {NULL, two, 0, 0}, /* psh/pul */
1249 [0x05] = {"rts", single, 0, 0},
1250 [0x06] = {"lea", opr_n_bytes_p1, reg, opr_decode},
1251 [0x07] = {"lea", opr_n_bytes_p1, reg, opr_decode},
1252 [0x08] = {"lea", opr_n_bytes_p1, lea_reg_xys_opr, 0},
1253 [0x09] = {"lea", opr_n_bytes_p1, lea_reg_xys_opr, 0},
1254 [0x0a] = {"lea", opr_n_bytes_p1, lea_reg_xys_opr, 0},
1255 [0x0b] = {NULL, loop_prim_n_bytes, 0, 0}, /* Loop primitives TBcc / DBcc */
1256 [0x0c] = {"mov.b", mov_imm_opr_n_bytes, mov_imm_opr, 0},
1257 [0x0d] = {"mov.w", mov_imm_opr_n_bytes, mov_imm_opr, 0},
1258 [0x0e] = {"mov.p", mov_imm_opr_n_bytes, mov_imm_opr, 0},
1259 [0x0f] = {"mov.l", mov_imm_opr_n_bytes, mov_imm_opr, 0},
1260 [0x10] = {NULL, shift_n_bytes, 0, 0}, /* lsr/lsl/asl/asr/rol/ror */
1261 [0x11] = {NULL, shift_n_bytes, 0, 0},
1262 [0x12] = {NULL, shift_n_bytes, 0, 0},
1263 [0x13] = {NULL, shift_n_bytes, 0, 0},
1264 [0x14] = {NULL, shift_n_bytes, 0, 0},
1265 [0x15] = {NULL, shift_n_bytes, 0, 0},
1266 [0x16] = {NULL, shift_n_bytes, 0, 0},
1267 [0x17] = {NULL, shift_n_bytes, 0, 0},
1268 [0x18] = {"lea", two, lea_reg_xys, NULL},
1269 [0x19] = {"lea", two, lea_reg_xys, NULL},
1270 [0x1a] = {"lea", two, lea_reg_xys, NULL},
1271 /* 0x1b PG2 */
1272 [0x1c] = {"mov.b", opr_n_bytes2, 0, opr_decode2},
1273 [0x1d] = {"mov.w", opr_n_bytes2, 0, opr_decode2},
1274 [0x1e] = {"mov.p", opr_n_bytes2, 0, opr_decode2},
1275 [0x1f] = {"mov.l", opr_n_bytes2, 0, opr_decode2},
1276 [0x20] = {"bra", pcrel_15bit, decode_rel_15_7, 0},
1277 [0x21] = {"bsr", pcrel_15bit, decode_rel_15_7, 0},
1278 [0x22] = {"bhi", pcrel_15bit, decode_rel_15_7, 0},
1279 [0x23] = {"bls", pcrel_15bit, decode_rel_15_7, 0},
1280 [0x24] = {"bcc", pcrel_15bit, decode_rel_15_7, 0},
1281 [0x25] = {"bcs", pcrel_15bit, decode_rel_15_7, 0},
1282 [0x26] = {"bne", pcrel_15bit, decode_rel_15_7, 0},
1283 [0x27] = {"beq", pcrel_15bit, decode_rel_15_7, 0},
1284 [0x28] = {"bvc", pcrel_15bit, decode_rel_15_7, 0},
1285 [0x29] = {"bvs", pcrel_15bit, decode_rel_15_7, 0},
1286 [0x2a] = {"bpl", pcrel_15bit, decode_rel_15_7, 0},
1287 [0x2b] = {"bmi", pcrel_15bit, decode_rel_15_7, 0},
1288 [0x2c] = {"bge", pcrel_15bit, decode_rel_15_7, 0},
1289 [0x2d] = {"blt", pcrel_15bit, decode_rel_15_7, 0},
1290 [0x2e] = {"bgt", pcrel_15bit, decode_rel_15_7, 0},
1291 [0x2f] = {"ble", pcrel_15bit, decode_rel_15_7, 0},
1292 [0x30] = {"inc", single, reg, 0},
1293 [0x31] = {"inc", single, reg, 0},
1294 [0x32] = {"inc", single, reg, 0},
1295 [0x33] = {"inc", single, reg, 0},
1296 [0x34] = {"inc", single, reg, 0},
1297 [0x35] = {"inc", single, reg, 0},
1298 [0x36] = {"inc", single, reg, 0},
1299 [0x37] = {"inc", single, reg, 0},
1300 [0x38] = {"clr", single, reg, 0},
1301 [0x39] = {"clr", single, reg, 0},
1302 [0x3a] = {"clr", single, reg, 0},
1303 [0x3b] = {"clr", single, reg, 0},
1304 [0x3c] = {"clr", single, reg, 0},
1305 [0x3d] = {"clr", single, reg, 0},
1306 [0x3e] = {"clr", single, reg, 0},
1307 [0x3f] = {"clr", single, reg, 0},
1308 [0x40] = {"dec", single, reg, 0},
1309 [0x41] = {"dec", single, reg, 0},
1310 [0x42] = {"dec", single, reg, 0},
1311 [0x43] = {"dec", single, reg, 0},
1312 [0x44] = {"dec", single, reg, 0},
1313 [0x45] = {"dec", single, reg, 0},
1314 [0x46] = {"dec", single, reg, 0},
1315 [0x47] = {"dec", single, reg, 0},
1316 [0x48] = {"mul", mul_n_bytes, mul_decode, 0},
1317 [0x49] = {"mul", mul_n_bytes, mul_decode, 0},
1318 [0x4a] = {"mul", mul_n_bytes, mul_decode, 0},
1319 [0x4b] = {"mul", mul_n_bytes, mul_decode, 0},
1320 [0x4c] = {"mul", mul_n_bytes, mul_decode, 0},
1321 [0x4d] = {"mul", mul_n_bytes, mul_decode, 0},
1322 [0x4e] = {"mul", mul_n_bytes, mul_decode, 0},
1323 [0x4f] = {"mul", mul_n_bytes, mul_decode, 0},
1324 [0x50] = {"add", three, reg, imm1234_0base},
1325 [0x51] = {"add", three, reg, imm1234_0base},
1326 [0x52] = {"add", three, reg, imm1234_0base},
1327 [0x53] = {"add", three, reg, imm1234_0base},
1328 [0x54] = {"add", two, reg, imm1234_0base},
1329 [0x55] = {"add", two, reg, imm1234_0base},
1330 [0x56] = {"add", five, reg, imm1234_0base},
1331 [0x57] = {"add", five, reg, imm1234_0base},
1332 [0x58] = {"and", three, reg, imm1234_8base},
1333 [0x59] = {"and", three, reg, imm1234_8base},
1334 [0x5a] = {"and", three, reg, imm1234_8base},
1335 [0x5b] = {"and", three, reg, imm1234_8base},
1336 [0x5c] = {"and", two, reg, imm1234_8base},
1337 [0x5d] = {"and", two, reg, imm1234_8base},
1338 [0x5e] = {"and", five, reg, imm1234_8base},
1339 [0x5f] = {"and", five, reg, imm1234_8base},
1340 [0x60] = {"add", opr_n_bytes_p1, reg, opr_decode},
1341 [0x61] = {"add", opr_n_bytes_p1, reg, opr_decode},
1342 [0x62] = {"add", opr_n_bytes_p1, reg, opr_decode},
1343 [0x63] = {"add", opr_n_bytes_p1, reg, opr_decode},
1344 [0x64] = {"add", opr_n_bytes_p1, reg, opr_decode},
1345 [0x65] = {"add", opr_n_bytes_p1, reg, opr_decode},
1346 [0x66] = {"add", opr_n_bytes_p1, reg, opr_decode},
1347 [0x67] = {"add", opr_n_bytes_p1, reg, opr_decode},
1348 [0x68] = {"and", opr_n_bytes_p1, reg, opr_decode},
1349 [0x69] = {"and", opr_n_bytes_p1, reg, opr_decode},
1350 [0x6a] = {"and", opr_n_bytes_p1, reg, opr_decode},
1351 [0x6b] = {"and", opr_n_bytes_p1, reg, opr_decode},
1352 [0x6c] = {"and", opr_n_bytes_p1, reg, opr_decode},
1353 [0x6d] = {"and", opr_n_bytes_p1, reg, opr_decode},
1354 [0x6e] = {"and", opr_n_bytes_p1, reg, opr_decode},
1355 [0x6f] = {"and", opr_n_bytes_p1, reg, opr_decode},
1356 [0x70] = {"sub", three, reg, imm1234_0base},
1357 [0x71] = {"sub", three, reg, imm1234_0base},
1358 [0x72] = {"sub", three, reg, imm1234_0base},
1359 [0x73] = {"sub", three, reg, imm1234_0base},
1360 [0x74] = {"sub", two, reg, imm1234_0base},
1361 [0x75] = {"sub", two, reg, imm1234_0base},
1362 [0x76] = {"sub", five, reg, imm1234_0base},
1363 [0x77] = {"sub", five, reg, imm1234_0base},
1364 [0x78] = {"or", three, reg, imm1234_8base},
1365 [0x79] = {"or", three, reg, imm1234_8base},
1366 [0x7a] = {"or", three, reg, imm1234_8base},
1367 [0x7b] = {"or", three, reg, imm1234_8base},
1368 [0x7c] = {"or", two, reg, imm1234_8base},
1369 [0x7d] = {"or", two, reg, imm1234_8base},
1370 [0x7e] = {"or", five, reg, imm1234_8base},
1371 [0x7f] = {"or", five, reg, imm1234_8base},
1372 [0x80] = {"sub", opr_n_bytes_p1, reg, opr_decode},
1373 [0x81] = {"sub", opr_n_bytes_p1, reg, opr_decode},
1374 [0x82] = {"sub", opr_n_bytes_p1, reg, opr_decode},
1375 [0x83] = {"sub", opr_n_bytes_p1, reg, opr_decode},
1376 [0x84] = {"sub", opr_n_bytes_p1, reg, opr_decode},
1377 [0x85] = {"sub", opr_n_bytes_p1, reg, opr_decode},
1378 [0x86] = {"sub", opr_n_bytes_p1, reg, opr_decode},
1379 [0x87] = {"sub", opr_n_bytes_p1, reg, opr_decode},
1380 [0x88] = {"or", opr_n_bytes_p1, reg, opr_decode},
1381 [0x89] = {"or", opr_n_bytes_p1, reg, opr_decode},
1382 [0x8a] = {"or", opr_n_bytes_p1, reg, opr_decode},
1383 [0x8b] = {"or", opr_n_bytes_p1, reg, opr_decode},
1384 [0x8c] = {"or", opr_n_bytes_p1, reg, opr_decode},
1385 [0x8d] = {"or", opr_n_bytes_p1, reg, opr_decode},
1386 [0x8e] = {"or", opr_n_bytes_p1, reg, opr_decode},
1387 [0x8f] = {"or", opr_n_bytes_p1, reg, opr_decode},
1388 [0x90] = {"ld", three, reg, imm1234_0base},
1389 [0x91] = {"ld", three, reg, imm1234_0base},
1390 [0x92] = {"ld", three, reg, imm1234_0base},
1391 [0x93] = {"ld", three, reg, imm1234_0base},
1392 [0x94] = {"ld", two, reg, imm1234_0base},
1393 [0x95] = {"ld", two, reg, imm1234_0base},
1394 [0x96] = {"ld", five, reg, imm1234_0base},
1395 [0x97] = {"ld", five, reg, imm1234_0base},
1396 [0x98] = {"ld", four, reg_xy, imm1234_0base},
1397 [0x99] = {"ld", four, reg_xy, imm1234_0base},
1398 [0x9a] = {"clr", single, reg_xy, 0},
1399 [0x9b] = {"clr", single, reg_xy, 0},
1400 [0x9c] = {"inc.b", opr_n_bytes_p1, 0, opr_decode},
1401 [0x9d] = {"inc.w", opr_n_bytes_p1, 0, opr_decode},
1402 [0x9e] = {"tfr", two, tfr, NULL},
1403 [0x9f] = {"inc.l", opr_n_bytes_p1, 0, opr_decode},
1404 [0xa0] = {"ld", opr_n_bytes_p1, reg, opr_decode},
1405 [0xa1] = {"ld", opr_n_bytes_p1, reg, opr_decode},
1406 [0xa2] = {"ld", opr_n_bytes_p1, reg, opr_decode},
1407 [0xa3] = {"ld", opr_n_bytes_p1, reg, opr_decode},
1408 [0xa4] = {"ld", opr_n_bytes_p1, reg, opr_decode},
1409 [0xa5] = {"ld", opr_n_bytes_p1, reg, opr_decode},
1410 [0xa6] = {"ld", opr_n_bytes_p1, reg, opr_decode},
1411 [0xa7] = {"ld", opr_n_bytes_p1, reg, opr_decode},
1412 [0xa8] = {"ld", opr_n_bytes_p1, reg_xy, opr_decode},
1413 [0xa9] = {"ld", opr_n_bytes_p1, reg_xy, opr_decode},
1414 [0xaa] = {"jmp", opr_n_bytes_p1, opr_decode, 0},
1415 [0xab] = {"jsr", opr_n_bytes_p1, opr_decode, 0},
1416 [0xac] = {"dec.b", opr_n_bytes_p1, 0, opr_decode},
1417 [0xad] = {"dec.w", opr_n_bytes_p1, 0, opr_decode},
1418 [0xae] = {NULL, two, 0, 0}, /* EXG / SEX */
1419 [0xaf] = {"dec.l", opr_n_bytes_p1, 0, opr_decode},
1420 [0xb0] = {"ld", four, reg, ext24_decode},
1421 [0xb1] = {"ld", four, reg, ext24_decode},
1422 [0xb2] = {"ld", four, reg, ext24_decode},
1423 [0xb3] = {"ld", four, reg, ext24_decode},
1424 [0xb4] = {"ld", four, reg, ext24_decode},
1425 [0xb5] = {"ld", four, reg, ext24_decode},
1426 [0xb6] = {"ld", four, reg, ext24_decode},
1427 [0xb7] = {"ld", four, reg, ext24_decode},
1428 [0xb8] = {"ld", four, reg_xy, ext24_decode},
1429 [0xb9] = {"ld", four, reg_xy, ext24_decode},
1430 [0xba] = {"jmp", four, ext24_decode, 0},
1431 [0xbb] = {"jsr", four, ext24_decode, 0},
1432 [0xbc] = {"clr.b", opr_n_bytes_p1, 0, opr_decode},
1433 [0xbd] = {"clr.w", opr_n_bytes_p1, 0, opr_decode},
1434 [0xbe] = {"clr.p", opr_n_bytes_p1, 0, opr_decode},
1435 [0xbf] = {"clr.l", opr_n_bytes_p1, 0, opr_decode},
1436 [0xc0] = {"st", opr_n_bytes_p1, reg, opr_decode},
1437 [0xc1] = {"st", opr_n_bytes_p1, reg, opr_decode},
1438 [0xc2] = {"st", opr_n_bytes_p1, reg, opr_decode},
1439 [0xc3] = {"st", opr_n_bytes_p1, reg, opr_decode},
1440 [0xc4] = {"st", opr_n_bytes_p1, reg, opr_decode},
1441 [0xc5] = {"st", opr_n_bytes_p1, reg, opr_decode},
1442 [0xc6] = {"st", opr_n_bytes_p1, reg, opr_decode},
1443 [0xc7] = {"st", opr_n_bytes_p1, reg, opr_decode},
1444 [0xc8] = {"st", opr_n_bytes_p1, reg_xy, opr_decode},
1445 [0xc9] = {"st", opr_n_bytes_p1, reg_xy, opr_decode},
1446 [0xca] = {"ld", three, reg_xy, ld_18bit_decode},
1447 [0xcb] = {"ld", three, reg_xy, ld_18bit_decode},
1448 [0xcc] = {"com.b", opr_n_bytes_p1, NULL, opr_decode},
1449 [0xcd] = {"com.w", opr_n_bytes_p1, NULL, opr_decode},
1450 [0xce] = {"andcc", two, imm1, 0},
1451 [0xcf] = {"com.l", opr_n_bytes_p1, NULL, opr_decode},
1452 [0xd0] = {"st", four, reg, ext24_decode},
1453 [0xd1] = {"st", four, reg, ext24_decode},
1454 [0xd2] = {"st", four, reg, ext24_decode},
1455 [0xd3] = {"st", four, reg, ext24_decode},
1456 [0xd4] = {"st", four, reg, ext24_decode},
1457 [0xd5] = {"st", four, reg, ext24_decode},
1458 [0xd6] = {"st", four, reg, ext24_decode},
1459 [0xd7] = {"st", four, reg, ext24_decode},
1460 [0xd8] = {"st", four, reg_xy, ext24_decode},
1461 [0xd9] = {"st", four, reg_xy, ext24_decode},
1462 [0xda] = {"ld", three, reg_xy, ld_18bit_decode},
1463 [0xdb] = {"ld", three, reg_xy, ld_18bit_decode},
1464 [0xdc] = {"neg.b", opr_n_bytes_p1, NULL, opr_decode},
1465 [0xdd] = {"neg.w", opr_n_bytes_p1, NULL, opr_decode},
1466 [0xde] = {"orcc", two, imm1, 0},
1467 [0xdf] = {"neg.l", opr_n_bytes_p1, NULL, opr_decode},
1468 [0xe0] = {"cmp", three, reg, imm1234_0base},
1469 [0xe1] = {"cmp", three, reg, imm1234_0base},
1470 [0xe2] = {"cmp", three, reg, imm1234_0base},
1471 [0xe3] = {"cmp", three, reg, imm1234_0base},
1472 [0xe4] = {"cmp", two, reg, imm1234_0base},
1473 [0xe5] = {"cmp", two, reg, imm1234_0base},
1474 [0xe6] = {"cmp", five, reg, imm1234_0base},
1475 [0xe7] = {"cmp", five, reg, imm1234_0base},
1476 [0xe8] = {"cmp", four, reg_xy, imm1234_0base},
1477 [0xe9] = {"cmp", four, reg_xy, imm1234_0base},
1478 [0xea] = {"ld", three, reg_xy, ld_18bit_decode},
1479 [0xeb] = {"ld", three, reg_xy, ld_18bit_decode},
1480 [0xec] = {"bclr", bm_n_bytes, bm_decode, 0},
1481 [0xed] = {"bset", bm_n_bytes, bm_decode, 0},
1482 [0xee] = {"btgl", bm_n_bytes, bm_decode, 0},
1483 [0xef] = {"!!invalid!!", NULL, NULL, NULL}, /* SPARE */
1484 [0xf0] = {"cmp", opr_n_bytes_p1, reg, opr_decode},
1485 [0xf1] = {"cmp", opr_n_bytes_p1, reg, opr_decode},
1486 [0xf2] = {"cmp", opr_n_bytes_p1, reg, opr_decode},
1487 [0xf3] = {"cmp", opr_n_bytes_p1, reg, opr_decode},
1488 [0xf4] = {"cmp", opr_n_bytes_p1, reg, opr_decode},
1489 [0xf5] = {"cmp", opr_n_bytes_p1, reg, opr_decode},
1490 [0xf6] = {"cmp", opr_n_bytes_p1, reg, opr_decode},
1491 [0xf7] = {"cmp", opr_n_bytes_p1, reg, opr_decode},
1492 [0xf8] = {"cmp", opr_n_bytes_p1, reg_xy, opr_decode},
1493 [0xf9] = {"cmp", opr_n_bytes_p1, reg_xy, opr_decode},
1494 [0xfa] = {"ld", three, reg_xy, ld_18bit_decode},
1495 [0xfb] = {"ld", three, reg_xy, ld_18bit_decode},
1496 [0xfc] = {"cmp", single, cmp_xy, 0},
1497 [0xfd] = {"sub", single, sub_d6_x_y, 0},
1498 [0xfe] = {"sub", single, sub_d6_y_x, 0},
1499 [0xff] = {"swi", single, 0, 0}
1500 };
1501
1502
1503 static const char *oprregs1[] =
1504 {
1505 "d3", "d2", "d1", "d0", "ccl", "cch"
1506 };
1507
1508 static const char *oprregs2[] =
1509 {
1510 "y", "x", "d7", "d6", "d5", "d4"
1511 };
1512
1513
1514
1515
1517 enum MUL_MODE
1518 {
1519 MUL_REG_REG,
1520 MUL_REG_OPR,
1521 MUL_REG_IMM,
1522 MUL_OPR_OPR
1523 };
1524
1525 struct mb
1526 {
1527 uint8_t mask;
1528 uint8_t value;
1529 enum MUL_MODE mode;
1530 };
1531
1532 static const struct mb mul_table[] = {
1533 {0x40, 0x00, MUL_REG_REG},
1534
1535 {0x47, 0x40, MUL_REG_OPR},
1536 {0x47, 0x41, MUL_REG_OPR},
1537 {0x47, 0x43, MUL_REG_OPR},
1538
1539 {0x47, 0x44, MUL_REG_IMM},
1540 {0x47, 0x45, MUL_REG_IMM},
1541 {0x47, 0x47, MUL_REG_IMM},
1542
1543 {0x43, 0x42, MUL_OPR_OPR},
1544 };
1545
1546 static void
1547 mul_decode (bfd_vma memaddr, struct disassemble_info* info)
1548 {
1549 uint8_t mb;
1550 int status = read_memory (memaddr, &mb, 1, info);
1551 if (status < 0)
1552 return;
1553
1554
1555 uint8_t byte;
1556 status = read_memory (memaddr - 1, &byte, 1, info);
1557 if (status < 0)
1558 return;
1559
1560 (*info->fprintf_func) (info->stream, "%c", (mb & 0x80) ? 's' : 'u');
1561
1562 enum MUL_MODE mode = -1;
1563 size_t i;
1564 for (i = 0; i < sizeof (mul_table) / sizeof (mul_table[0]); ++i)
1565 {
1566 const struct mb *mm = mul_table + i;
1567 if ((mb & mm->mask) == mm->value)
1568 {
1569 mode = mm->mode;
1570 break;
1571 }
1572 }
1573
1574 switch (mode)
1575 {
1576 case MUL_REG_REG:
1577 break;
1578 case MUL_OPR_OPR:
1579 {
1580 int size1 = (mb & 0x30) >> 4;
1581 int size2 = (mb & 0x0c) >> 2;
1582 (*info->fprintf_func) (info->stream, ".%c%c",
1583 shift_size_table [size1],
1584 shift_size_table [size2]);
1585 }
1586 break;
1587 default:
1588 {
1589 int size = (mb & 0x3);
1590 (*info->fprintf_func) (info->stream, ".%c", shift_size_table [size]);
1591 }
1592 break;
1593 }
1594
1595 operand_separator (info);
1596 (*info->fprintf_func) (info->stream, "%s", registers[byte & 0x7].name);
1597
1598 switch (mode)
1599 {
1600 case MUL_REG_REG:
1601 case MUL_REG_IMM:
1602 case MUL_REG_OPR:
1603 operand_separator (info);
1604 (*info->fprintf_func) (info->stream, "%s", registers[(mb & 0x38) >> 3].name);
1605 break;
1606 default:
1607 break;
1608 }
1609
1610 switch (mode)
1611 {
1612 case MUL_REG_IMM:
1613 operand_separator (info);
1614 int size = (mb & 0x3);
1615 uint32_t imm = decode_signed_value (memaddr + 1, info, size + 1);
1616 (*info->fprintf_func) (info->stream, "#%d", imm);
1617 break;
1618 case MUL_REG_REG:
1619 operand_separator (info);
1620 (*info->fprintf_func) (info->stream, "%s", registers[mb & 0x07].name);
1621 break;
1622 case MUL_REG_OPR:
1623 opr_decode (memaddr + 1, info);
1624 break;
1625 case MUL_OPR_OPR:
1626 {
1627 int first = opr_n_bytes (memaddr + 1, info);
1628 opr_decode (memaddr + 1, info);
1629 opr_decode (memaddr + first + 1, info);
1630 break;
1631 }
1632 }
1633 }
1634
1635
1636 static int
1637 mul_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
1638 {
1639 int nx = 2;
1640 uint8_t mb;
1641 int status = read_memory (memaddr, &mb, 1, info);
1642 if (status < 0)
1643 return 0;
1644
1645 enum MUL_MODE mode = -1;
1646 size_t i;
1647 for (i = 0; i < sizeof (mul_table) / sizeof (mul_table[0]); ++i)
1648 {
1649 const struct mb *mm = mul_table + i;
1650 if ((mb & mm->mask) == mm->value)
1651 {
1652 mode = mm->mode;
1653 break;
1654 }
1655 }
1656
1657 int size = (mb & 0x3) + 1;
1658
1659 switch (mode)
1660 {
1661 case MUL_REG_IMM:
1662 nx += size;
1663 break;
1664 case MUL_REG_REG:
1665 break;
1666 case MUL_REG_OPR:
1667 nx += opr_n_bytes (memaddr + 1, info);
1668 break;
1669 case MUL_OPR_OPR:
1670 {
1671 int first = opr_n_bytes (memaddr + nx - 1, info);
1672 nx += first;
1673 int second = opr_n_bytes (memaddr + nx - 1, info);
1674 nx += second;
1675 }
1676 break;
1677 }
1678
1679 return nx;
1680 }
1681
1682
1683 enum BM_MODE {
1685 BM_REG_IMM,
1686 BM_RESERVED0,
1687 BM_OPR_B,
1688 BM_OPR_W,
1689 BM_OPR_L,
1690 BM_OPR_REG,
1691 BM_RESERVED1
1692 };
1693
1694 struct bm
1695 {
1696 uint8_t mask;
1697 uint8_t value;
1698 enum BM_MODE mode;
1699 };
1700
1701 static const struct bm bm_table[] = {
1702 { 0xC6, 0x04, BM_REG_IMM},
1703 { 0x84, 0x00, BM_REG_IMM},
1704 { 0x06, 0x06, BM_REG_IMM},
1705 { 0xC6, 0x44, BM_RESERVED0},
1706 // 00
1707 { 0x8F, 0x80, BM_OPR_B},
1708 { 0x8E, 0x82, BM_OPR_W},
1709 { 0x8C, 0x88, BM_OPR_L},
1710
1711 { 0x83, 0x81, BM_OPR_REG},
1712 { 0x87, 0x84, BM_RESERVED1},
1713 };
1714
1715 static void
1716 bm_decode (bfd_vma memaddr, struct disassemble_info* info)
1717 {
1718 uint8_t bm;
1719 int status = read_memory (memaddr, &bm, 1, info);
1720 if (status < 0)
1721 return;
1722
1723 size_t i;
1724 enum BM_MODE mode = -1;
1725 for (i = 0; i < sizeof (bm_table) / sizeof (bm_table[0]); ++i)
1726 {
1727 const struct bm *bme = bm_table + i;
1728 if ((bm & bme->mask) == bme->value)
1729 {
1730 mode = bme->mode;
1731 break;
1732 }
1733 }
1734
1735 switch (mode)
1736 {
1737 case BM_REG_IMM:
1738 operand_separator (info);
1739 (*info->fprintf_func) (info->stream, "%s", registers[bm & 0x07].name);
1740 break;
1741 case BM_OPR_B:
1742 (*info->fprintf_func) (info->stream, ".%c", 'b');
1743 opr_decode (memaddr + 1, info);
1744 break;
1745 case BM_OPR_W:
1746 (*info->fprintf_func) (info->stream, ".%c", 'w');
1747 opr_decode (memaddr + 1, info);
1748 break;
1749 case BM_OPR_L:
1750 (*info->fprintf_func) (info->stream, ".%c", 'l');
1751 opr_decode (memaddr + 1, info);
1752 break;
1753 case BM_OPR_REG:
1754 {
1755 uint8_t xb;
1756 read_memory (memaddr + 1, &xb, 1, info);
1757 /* Don't emit a size suffix for register operands */
1758 if ((xb & 0xF8) != 0xB8)
1759 (*info->fprintf_func) (info->stream, ".%c", shift_size_table[(bm & 0x0c) >> 2]);
1760 opr_decode (memaddr + 1, info);
1761 }
1762 break;
1763 case BM_RESERVED0:
1764 case BM_RESERVED1:
1765 assert (0);
1766 break;
1767 }
1768
1769 uint8_t imm = 0;
1770 operand_separator (info);
1771 switch (mode)
1772 {
1773 case BM_REG_IMM:
1774 {
1775 imm = (bm & 0xF8) >> 3;
1776 (*info->fprintf_func) (info->stream, "#%d", imm);
1777 }
1778 break;
1779 case BM_OPR_L:
1780 imm |= (bm & 0x03) << 3;
1781 /* fallthrough */
1782 case BM_OPR_W:
1783 imm |= (bm & 0x01) << 3;
1784 /* fallthrough */
1785 case BM_OPR_B:
1786 imm |= (bm & 0x70) >> 4;
1787 (*info->fprintf_func) (info->stream, "#%d", imm);
1788 break;
1789 case BM_OPR_REG:
1790 (*info->fprintf_func) (info->stream, "%s", registers[(bm & 0x70) >> 4].name);
1791 break;
1792 case BM_RESERVED0:
1793 case BM_RESERVED1:
1794 assert (0);
1795 break;
1796 }
1797 }
1798
1799
1800 static void
1801 bm_rel_decode (bfd_vma memaddr, struct disassemble_info* info)
1802 {
1803 uint8_t bm;
1804 int status = read_memory (memaddr, &bm, 1, info);
1805 if (status < 0)
1806 return;
1807
1808 size_t i;
1809 enum BM_MODE mode = -1;
1810 for (i = 0; i < sizeof (bm_table) / sizeof (bm_table[0]); ++i)
1811 {
1812 const struct bm *bme = bm_table + i;
1813 if ((bm & bme->mask) == bme->value)
1814 {
1815 mode = bme->mode;
1816 break;
1817 }
1818 }
1819
1820 switch (mode)
1821 {
1822 case BM_REG_IMM:
1823 break;
1824 case BM_OPR_B:
1825 (*info->fprintf_func) (info->stream, ".%c", 'b');
1826 break;
1827 case BM_OPR_W:
1828 (*info->fprintf_func) (info->stream, ".%c", 'w');
1829 break;
1830 case BM_OPR_L:
1831 (*info->fprintf_func) (info->stream, ".%c", 'l');
1832 break;
1833 case BM_OPR_REG:
1834 {
1835 uint8_t xb;
1836 read_memory (memaddr + 1, &xb, 1, info);
1837 /* Don't emit a size suffix for register operands */
1838 if ((xb & 0xF8) != 0xB8)
1839 (*info->fprintf_func) (info->stream, ".%c",
1840 shift_size_table[(bm & 0x0C) >> 2]);
1841 }
1842 break;
1843 case BM_RESERVED0:
1844 case BM_RESERVED1:
1845 assert (0);
1846 break;
1847 }
1848
1849 int n = 1;
1850 switch (mode)
1851 {
1852 case BM_REG_IMM:
1853 operand_separator (info);
1854 (*info->fprintf_func) (info->stream, "%s", registers[bm & 0x07].name);
1855 break;
1856 case BM_OPR_B:
1857 case BM_OPR_W:
1858 case BM_OPR_L:
1859 opr_decode (memaddr + 1, info);
1860 n = 1 + opr_n_bytes (memaddr + 1, info);
1861 break;
1862 case BM_OPR_REG:
1863 opr_decode (memaddr + 1, info);
1864 break;
1865 case BM_RESERVED0:
1866 case BM_RESERVED1:
1867 assert (0);
1868 break;
1869 }
1870
1871
1872 int imm = 0;
1873 operand_separator (info);
1874 switch (mode)
1875 {
1876 case BM_OPR_L:
1877 imm |= (bm & 0x02) << 3;
1878 /* fall through */
1879 case BM_OPR_W:
1880 imm |= (bm & 0x01) << 3;
1881 /* fall through */
1882 case BM_OPR_B:
1883 imm |= (bm & 0x70) >> 4;
1884 (*info->fprintf_func) (info->stream, "#%d", imm);
1885 break;
1886 case BM_REG_IMM:
1887 imm = (bm & 0xF8) >> 3;
1888 (*info->fprintf_func) (info->stream, "#%d", imm);
1889 break;
1890 case BM_RESERVED0:
1891 case BM_RESERVED1:
1892 assert (0);
1893 break;
1894 case BM_OPR_REG:
1895 (*info->fprintf_func) (info->stream, "%s", registers[(bm & 0x70) >> 4].name);
1896 n += opr_n_bytes (memaddr + 1, info);
1897 break;
1898 }
1899
1900 rel_15_7 (memaddr + n, info, n + 1);
1901 }
1902
1903 static int
1904 bm_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
1905 {
1906 uint8_t bm;
1907 int status = read_memory (memaddr, &bm, 1, info);
1908 if (status < 0)
1909 return status;
1910
1911 size_t i;
1912 enum BM_MODE mode = -1;
1913 for (i = 0; i < sizeof (bm_table) / sizeof (bm_table[0]); ++i)
1914 {
1915 const struct bm *bme = bm_table + i;
1916 if ((bm & bme->mask) == bme->value)
1917 {
1918 mode = bme->mode;
1919 break;
1920 }
1921 }
1922
1923 int n = 2;
1924 switch (mode)
1925 {
1926 case BM_REG_IMM:
1927 break;
1928
1929 case BM_OPR_B:
1930 case BM_OPR_W:
1931 case BM_OPR_L:
1932 n += opr_n_bytes (memaddr + 1, info);
1933 break;
1934 case BM_OPR_REG:
1935 n += opr_n_bytes (memaddr + 1, info);
1936 break;
1937 default:
1938 break;
1939 }
1940
1941 return n;
1942 }
1943
1944 static int
1945 bm_rel_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
1946 {
1947 int n = 1 + bm_n_bytes (memaddr, info);
1948
1949 bfd_byte rb;
1950 int status = read_memory (memaddr + n - 2, &rb, 1, info);
1951 if (status != 0)
1952 return status;
1953
1954 if (rb & 0x80)
1955 n++;
1956
1957 return n;
1958 }
1959
1960
1961
1962
1964
1965 /* shift direction */
1966 enum SB_DIR
1967 {
1968 SB_LEFT,
1969 SB_RIGHT
1970 };
1971
1972 enum SB_TYPE
1973 {
1974 SB_ARITHMETIC,
1975 SB_LOGICAL
1976 };
1977
1978
1979 enum SB_MODE
1980 {
1981 SB_REG_REG_N_EFF,
1982 SB_REG_REG_N,
1983 SB_REG_OPR_EFF,
1984 SB_ROT,
1985 SB_REG_OPR_OPR,
1986 SB_OPR_N
1987 };
1988
1989 struct sb
1990 {
1991 uint8_t mask;
1992 uint8_t value;
1993 enum SB_MODE mode;
1994 };
1995
1996 static const struct sb sb_table[] = {
1997 {0x30, 0x00, SB_REG_REG_N_EFF},
1998 {0x30, 0x10, SB_REG_REG_N},
1999 {0x34, 0x20, SB_REG_OPR_EFF},
2000 {0x34, 0x24, SB_ROT},
2001 {0x34, 0x30, SB_REG_OPR_OPR},
2002 {0x34, 0x34, SB_OPR_N},
2003 };
2004
2005 static int
2006 shift_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
2007 {
2008 bfd_byte sb;
2009 int status = read_memory (memaddr++, &sb, 1, info);
2010 if (status != 0)
2011 return status;
2012
2013 size_t i;
2014 enum SB_MODE mode = -1;
2015 for (i = 0; i < sizeof (sb_table) / sizeof (sb_table[0]); ++i)
2016 {
2017 const struct sb *sbe = sb_table + i;
2018 if ((sb & sbe->mask) == sbe->value)
2019 mode = sbe->mode;
2020 }
2021
2022 switch (mode)
2023 {
2024 case SB_REG_REG_N_EFF:
2025 return 2;
2026 break;
2027 case SB_REG_OPR_EFF:
2028 case SB_ROT:
2029 return 2 + opr_n_bytes (memaddr, info);
2030 break;
2031 case SB_REG_OPR_OPR:
2032 {
2033 int opr1 = opr_n_bytes (memaddr, info);
2034 int opr2 = 0;
2035 if ((sb & 0x30) != 0x20)
2036 opr2 = opr_n_bytes (memaddr + opr1, info);
2037 return 2 + opr1 + opr2;
2038 }
2039 break;
2040 default:
2041 return 3;
2042 }
2043
2044 /* not reached */
2045 return -1;
2046 }
2047
2048
2050 static int
2051 mov_imm_opr_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
2052 {
2053 bfd_byte byte;
2054 int status = read_memory (memaddr - 1, &byte, 1, info);
2055 if (status < 0)
2056 return status;
2057
2058 int size = byte - 0x0c + 1;
2059
2060 return size + opr_n_bytes (memaddr + size, info) + 1;
2061 }
2062
2063 static void
2064 mov_imm_opr (bfd_vma memaddr, struct disassemble_info* info)
2065 {
2066 bfd_byte byte;
2067 int status = read_memory (memaddr - 1, &byte, 1, info);
2068 if (status < 0)
2069 return ;
2070
2071 int size = byte - 0x0c + 1;
2072 uint32_t imm = decode_signed_value (memaddr, info, size);
2073
2074 operand_separator (info);
2075 (*info->fprintf_func) (info->stream, "#%d", imm);
2076 opr_decode (memaddr + size, info);
2077 }
2078
2079
2080
2082 static void
2083 ld_18bit_decode (bfd_vma memaddr, struct disassemble_info* info)
2084 {
2085 size_t size = 3;
2086 bfd_byte buffer[3];
2087 int status = read_memory (memaddr, buffer + 1, 2, info);
2088 if (status < 0)
2089 return ;
2090
2091
2092 status = read_memory (memaddr - 1, buffer, 1, info);
2093 if (status < 0)
2094 return ;
2095
2096 buffer[0] = (buffer[0] & 0x30) >> 4;
2097
2098 size_t i;
2099 uint32_t imm = 0;
2100 for (i = 0; i < size; ++i)
2101 {
2102 imm |= buffer[i] << (8 * (size - i - 1));
2103 }
2104
2105 operand_separator (info);
2106 (*info->fprintf_func) (info->stream, "#%d", imm);
2107 }
2108
2109
2110
2112 /* Loop Primitives */
2113
2114 enum LP_MODE {
2115 LP_REG,
2116 LP_XY,
2117 LP_OPR
2118 };
2119
2120 struct lp
2121 {
2122 uint8_t mask;
2123 uint8_t value;
2124 enum LP_MODE mode;
2125 };
2126
2127 static const struct lp lp_mode[] = {
2128 {0x08, 0x00, LP_REG},
2129 {0x0C, 0x08, LP_XY},
2130 {0x0C, 0x0C, LP_OPR},
2131 };
2132
2133
2134 static const char *lb_condition[] =
2135 {
2136 "ne", "eq", "pl", "mi", "gt", "le",
2137 "??", "??"
2138 };
2139
2140 static int
2141 loop_prim_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
2142 {
2143 int mx = 0;
2144 uint8_t lb;
2145 read_memory (memaddr + mx++, &lb, 1, info);
2146
2147 enum LP_MODE mode = -1;
2148 size_t i;
2149 for (i = 0; i < sizeof (lp_mode) / sizeof (lp_mode[0]); ++i)
2150 {
2151 const struct lp *pb = lp_mode + i;
2152 if ((lb & pb->mask) == pb->value)
2153 {
2154 mode = pb->mode;
2155 break;
2156 }
2157 }
2158
2159 if (mode == LP_OPR)
2160 {
2161 mx += opr_n_bytes (memaddr + mx, info) ;
2162 }
2163
2164 uint8_t rb;
2165 read_memory (memaddr + mx++, &rb, 1, info);
2166 if (rb & 0x80)
2167 mx++;
2168
2169 return mx + 1;
2170 }
2171
2172
2173
2174
2176 static int
2177 print_insn_exg_sex (bfd_vma memaddr, struct disassemble_info* info)
2178 {
2179 uint8_t eb;
2180 int status = read_memory (memaddr, &eb, 1, info);
2181 if (status < 0)
2182 return -1;
2183
2184 const struct reg *first = ®isters[(eb & 0xf0) >> 4];
2185 const struct reg *second = ®isters[(eb & 0xf)];
2186
2187 if (first->bytes < second->bytes)
2188 (*info->fprintf_func) (info->stream, "sex");
2189 else
2190 (*info->fprintf_func) (info->stream, "exg");
2191
2192 operand_separator (info);
2193 (*info->fprintf_func) (info->stream, "%s", first->name);
2194 operand_separator (info);
2195 (*info->fprintf_func) (info->stream, "%s", second->name);
2196 return 0;
2197 }
2198
2199
2200
2201 static int
2202 print_insn_loop_primitive (bfd_vma memaddr, struct disassemble_info* info)
2203 {
2204 int offs = 1;
2205 uint8_t lb;
2206 int status = read_memory (memaddr, &lb, 1, info);
2207
2208 char mnemonic[7];
2209 int x = 0;
2210 mnemonic[x++] = (lb & 0x80) ? 'd' : 't';
2211 mnemonic[x++] = 'b';
2212 stpcpy (mnemonic + x, lb_condition [(lb & 0x70) >> 4]);
2213 x += 2;
2214
2215 const char *reg = NULL;
2216 enum LP_MODE mode = -1;
2217 size_t i;
2218 for (i = 0; i < sizeof (lp_mode) / sizeof (lp_mode[0]); ++i)
2219 {
2220 const struct lp *pb = lp_mode + i;
2221 if ((lb & pb->mask) == pb->value)
2222 {
2223 mode = pb->mode;
2224 break;
2225 }
2226 }
2227
2228 switch (mode)
2229 {
2230 case LP_REG:
2231 reg = registers [lb & 0x07].name;
2232 break;
2233 case LP_XY:
2234 reg = (lb & 0x1) ? "y" : "x";
2235 break;
2236 case LP_OPR:
2237 mnemonic[x++] = '.';
2238 mnemonic[x++] = shift_size_table [lb & 0x03];
2239 offs += opr_n_bytes (memaddr + 1, info);
2240 break;
2241 }
2242
2243 mnemonic[x++] = '\0';
2244
2245 (*info->fprintf_func) (info->stream, "%s", mnemonic);
2246
2247 if (mode == LP_OPR)
2248 opr_decode (memaddr + 1, info);
2249 else
2250 {
2251 operand_separator (info);
2252 (*info->fprintf_func) (info->stream, "%s", reg);
2253 }
2254
2255 rel_15_7 (memaddr + offs, info, offs + 1);
2256
2257 return status;
2258 }
2259
2260
2261 static int
2262 print_insn_shift (bfd_vma memaddr, struct disassemble_info* info, uint8_t byte)
2263 {
2264 size_t i;
2265 uint8_t sb;
2266 int status = read_memory (memaddr, &sb, 1, info);
2267 if (status < 0)
2268 return status;
2269
2270 enum SB_DIR dir = (sb & 0x40) ? SB_LEFT : SB_RIGHT;
2271 enum SB_TYPE type = (sb & 0x80) ? SB_ARITHMETIC : SB_LOGICAL;
2272 enum SB_MODE mode = -1;
2273 for (i = 0; i < sizeof (sb_table) / sizeof (sb_table[0]); ++i)
2274 {
2275 const struct sb *sbe = sb_table + i;
2276 if ((sb & sbe->mask) == sbe->value)
2277 mode = sbe->mode;
2278 }
2279
2280 char mnemonic[6];
2281 int x = 0;
2282 if (mode == SB_ROT)
2283 {
2284 mnemonic[x++] = 'r';
2285 mnemonic[x++] = 'o';
2286 }
2287 else
2288 {
2289 mnemonic[x++] = (type == SB_LOGICAL) ? 'l' : 'a';
2290 mnemonic[x++] = 's';
2291 }
2292
2293 mnemonic[x++] = (dir == SB_LEFT) ? 'l' : 'r';
2294
2295 switch (mode)
2296 {
2297 case SB_REG_OPR_EFF:
2298 case SB_ROT:
2299 case SB_REG_OPR_OPR:
2300 mnemonic[x++] = '.';
2301 mnemonic[x++] = shift_size_table[sb & 0x03];
2302 break;
2303 case SB_OPR_N:
2304 {
2305 uint8_t xb;
2306 read_memory (memaddr + 1, &xb, 1, info);
2307 /* The size suffix is not printed if the OPR operand refers
2308 directly to a register, because the size is implied by the
2309 size of that register. */
2310 if ((xb & 0xF8) != 0xB8)
2311 {
2312 mnemonic[x++] = '.';
2313 mnemonic[x++] = shift_size_table[sb & 0x03];
2314 }
2315 }
2316 break;
2317 default:
2318 break;
2319 };
2320
2321 mnemonic[x++] = '\0';
2322
2323 (*info->fprintf_func) (info->stream, "%s", mnemonic);
2324
2325 /* Destination register */
2326 switch (mode)
2327 {
2328 case SB_REG_REG_N_EFF:
2329 case SB_REG_REG_N:
2330 case SB_REG_OPR_EFF:
2331 case SB_REG_OPR_OPR:
2332 operand_separator (info);
2333 (*info->fprintf_func) (info->stream, "%s", registers[byte & 0x7].name);
2334 break;
2335
2336 case SB_ROT:
2337 opr_decode (memaddr + 1, info);
2338 break;
2339
2340 default:
2341 break;
2342 }
2343
2344 /* Source register */
2345 switch (mode)
2346 {
2347 case SB_REG_REG_N_EFF:
2348 case SB_REG_REG_N:
2349 operand_separator (info);
2350 (*info->fprintf_func) (info->stream, "%s", registers[sb & 0x7].name);
2351 break;
2352
2353 case SB_REG_OPR_OPR:
2354 opr_decode (memaddr + 1, info);
2355 break;
2356
2357 default:
2358 break;
2359 }
2360
2361 /* 3rd arg */
2362 switch (mode)
2363 {
2364 case SB_REG_OPR_EFF:
2365 case SB_OPR_N:
2366 opr_decode (memaddr + 1, info);
2367 break;
2368
2369 case SB_REG_REG_N:
2370 if (sb & 0x08)
2371 {
2372 operand_separator (info);
2373 if (byte & 0x10)
2374 {
2375 uint8_t xb;
2376 read_memory (memaddr + 1, &xb, 1, info);
2377 int shift = ((sb & 0x08) >> 3) | ((xb & 0x0f) << 1);
2378 (*info->fprintf_func) (info->stream, "#%d", shift);
2379 }
2380 else
2381 {
2382 (*info->fprintf_func) (info->stream, "%s:%d", __FILE__, __LINE__);
2383 }
2384 }
2385 else
2386 {
2387 opr_decode (memaddr + 1, info);
2388 }
2389 break;
2390 case SB_REG_OPR_OPR:
2391 {
2392 uint8_t xb;
2393 int n = opr_n_bytes (memaddr + 1, info);
2394 read_memory (memaddr + 1 + n, &xb, 1, info);
2395
2396 if ((xb & 0xF0) == 0x70)
2397 {
2398 int imm = xb & 0x0F;
2399 imm <<= 1;
2400 imm |= (sb & 0x08) >> 3;
2401 operand_separator (info);
2402 (*info->fprintf_func) (info->stream, "#%d", imm);
2403 }
2404 else
2405 {
2406 opr_decode (memaddr + 1 + n, info);
2407 }
2408 }
2409 break;
2410 default:
2411 break;
2412 }
2413
2414 switch (mode)
2415 {
2416 case SB_REG_REG_N_EFF:
2417 case SB_REG_OPR_EFF:
2418 case SB_OPR_N:
2419 operand_separator (info);
2420 (*info->fprintf_func) (info->stream, "#%d",
2421 (sb & 0x08) ? 2 : 1);
2422 break;
2423
2424 default:
2425 break;
2426 }
2427
2428 return 0;
2429 }
2430
2431 int
2432 print_insn_s12z (bfd_vma memaddr, struct disassemble_info* info)
2433 {
2434 bfd_byte byte;
2435 int status = read_memory (memaddr++, &byte, 1, info);
2436 if (status != 0)
2437 return status;
2438
2439 const struct opcode *opc2 = NULL;
2440 const struct opcode *opc = page1 + byte;
2441 if (opc->mnemonic)
2442 {
2443 (*info->fprintf_func) (info->stream, "%s", opc->mnemonic);
2444 }
2445 else
2446 {
2447 /* The special cases ... */
2448 switch (byte)
2449 {
2450 case PAGE2_PREBYTE:
2451 {
2452 bfd_byte byte2;
2453 read_memory (memaddr++, &byte2, 1, info);
2454 opc2 = page2 + byte2;
2455 if (opc2->mnemonic)
2456 {
2457 (*info->fprintf_func) (info->stream, "%s", opc2->mnemonic);
2458
2459 if (opc2->operands)
2460 {
2461 opc2->operands (memaddr, info);
2462 }
2463
2464 if (opc2->operands2)
2465 {
2466 opc2->operands2 (memaddr, info);
2467 }
2468 }
2469 else if (byte2 >= 0x08 && byte2 <= 0x1F)
2470 {
2471 bfd_byte bb;
2472 read_memory (memaddr, &bb, 1, info);
2473 if (bb & 0x80)
2474 (*info->fprintf_func) (info->stream, "bfins");
2475 else
2476 (*info->fprintf_func) (info->stream, "bfext");
2477
2478 enum BB_MODE mode = -1;
2479 size_t i;
2480 const struct opr_bb *bbs = 0;
2481 for (i = 0; i < sizeof (bb_modes) / sizeof (bb_modes[0]); ++i)
2482 {
2483 bbs = bb_modes + i;
2484 if ((bb & bbs->mask) == bbs->value)
2485 {
2486 mode = bbs->mode;
2487 break;
2488 }
2489 }
2490
2491 switch (mode)
2492 {
2493 case BB_REG_OPR_REG:
2494 case BB_REG_OPR_IMM:
2495 case BB_OPR_REG_REG:
2496 case BB_OPR_REG_IMM:
2497 {
2498 int size = (bb >> 2) & 0x03;
2499 (*info->fprintf_func) (info->stream, ".%c",
2500 shift_size_table [size]);
2501 }
2502 break;
2503 default:
2504 break;
2505 }
2506
2507 int reg1 = byte2 & 0x07;
2508 /* First operand */
2509 switch (mode)
2510 {
2511 case BB_REG_REG_REG:
2512 case BB_REG_REG_IMM:
2513 case BB_REG_OPR_REG:
2514 case BB_REG_OPR_IMM:
2515 operand_separator (info);
2516 (*info->fprintf_func) (info->stream, "%s",
2517 registers[reg1].name);
2518 break;
2519 case BB_OPR_REG_REG:
2520 opr_decode (memaddr + 1, info);
2521 break;
2522 case BB_OPR_REG_IMM:
2523 opr_decode (memaddr + 2, info);
2524 break;
2525 }
2526
2527 /* Second operand */
2528 switch (mode)
2529 {
2530 case BB_REG_REG_REG:
2531 case BB_REG_REG_IMM:
2532 {
2533 int reg_src = (bb >> 2) & 0x07;
2534 operand_separator (info);
2535 (*info->fprintf_func) (info->stream, "%s",
2536 registers[reg_src].name);
2537 }
2538 break;
2539 case BB_OPR_REG_REG:
2540 case BB_OPR_REG_IMM:
2541 {
2542 int reg_src = (byte2 & 0x07);
2543 operand_separator (info);
2544 (*info->fprintf_func) (info->stream, "%s",
2545 registers[reg_src].name);
2546 }
2547 break;
2548 case BB_REG_OPR_REG:
2549 opr_decode (memaddr + 1, info);
2550 break;
2551 case BB_REG_OPR_IMM:
2552 opr_decode (memaddr + 2, info);
2553 break;
2554 }
2555
2556 /* Third operand */
2557 operand_separator (info);
2558 switch (mode)
2559 {
2560 case BB_REG_REG_REG:
2561 case BB_OPR_REG_REG:
2562 case BB_REG_OPR_REG:
2563 {
2564 int reg_parm = bb & 0x03;
2565 (*info->fprintf_func) (info->stream, "%s",
2566 registers[reg_parm].name);
2567 }
2568 break;
2569 case BB_REG_REG_IMM:
2570 case BB_OPR_REG_IMM:
2571 case BB_REG_OPR_IMM:
2572 {
2573 bfd_byte i1;
2574 read_memory (memaddr + 1, &i1, 1, info);
2575 int offset = i1 & 0x1f;
2576 int width = bb & 0x03;
2577 width <<= 3;
2578 width |= i1 >> 5;
2579 (*info->fprintf_func) (info->stream, "#%d:%d", width, offset);
2580 }
2581 break;
2582 }
2583 }
2584 }
2585 break;
2586 case 0xae: /* EXG / SEX */
2587 status = print_insn_exg_sex (memaddr, info);
2588 break;
2589 case 0x0b: /* Loop Primitives TBcc and DBcc */
2590 status = print_insn_loop_primitive (memaddr, info);
2591 break;
2592 case 0x10: /* shift */
2593 case 0x11: /* shift */
2594 case 0x12: /* shift */
2595 case 0x13: /* shift */
2596 case 0x14: /* shift */
2597 case 0x15: /* shift */
2598 case 0x16: /* shift */
2599 case 0x17: /* shift */
2600 status = print_insn_shift (memaddr, info, byte);
2601 break;
2602 case 0x04: /* psh / pul */
2603 {
2604 read_memory (memaddr, &byte, 1, info);
2605 (*info->fprintf_func) (info->stream, (byte & 0x80) ? "pul" : "psh");
2606 int bit;
2607 if (byte & 0x40)
2608 {
2609 if ((byte & 0x3F) == 0)
2610 {
2611 operand_separator (info);
2612 (*info->fprintf_func) (info->stream, "%s", "ALL16b");
2613 }
2614 else
2615 for (bit = 5; bit >= 0; --bit)
2616 {
2617 if (byte & (0x1 << bit))
2618 {
2619 operand_separator (info);
2620 (*info->fprintf_func) (info->stream, "%s", oprregs2[bit]);
2621 }
2622 }
2623 }
2624 else
2625 {
2626 if ((byte & 0x3F) == 0)
2627 {
2628 operand_separator (info);
2629 (*info->fprintf_func) (info->stream, "%s", "ALL");
2630 }
2631 else
2632 for (bit = 5; bit >= 0; --bit)
2633 {
2634 if (byte & (0x1 << bit))
2635 {
2636 operand_separator (info);
2637 (*info->fprintf_func) (info->stream, "%s", oprregs1[bit]);
2638 }
2639 }
2640 }
2641 }
2642 break;
2643 default:
2644 operand_separator (info);
2645 (*info->fprintf_func) (info->stream, "???");
2646 break;
2647 }
2648 }
2649
2650 if (opc2 == NULL)
2651 {
2652 if (opc->operands)
2653 {
2654 opc->operands (memaddr, info);
2655 }
2656
2657 if (opc->operands2)
2658 {
2659 opc->operands2 (memaddr, info);
2660 }
2661 }
2662
2663 int n = 0;
2664
2665 /* Opcodes in page2 have an additional byte */
2666 if (opc2)
2667 n++;
2668
2669 if (opc2 && opc2->insn_bytes == 0)
2670 return n;
2671
2672 if (!opc2 && opc->insn_bytes == 0)
2673 return n;
2674
2675 if (opc2)
2676 n += opc2->insn_bytes (memaddr, info);
2677 else
2678 n += opc->insn_bytes (memaddr, info);
2679
2680 return n;
2681 }
2682