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