]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - opcodes/s12z-dis.c
AArch64: Add SVE constraints verifier.
[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
7ba3ba91 27#include "opcode/s12z.h"
7b4ae824
JD
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
9dcb0ba4 814 char *reg_xys = NULL;
7b4ae824
JD
815 switch (byte & 0x03)
816 {
817 case 0x00:
9dcb0ba4 818 reg_xys = "x";
7b4ae824
JD
819 break;
820 case 0x01:
9dcb0ba4 821 reg_xys = "y";
7b4ae824
JD
822 break;
823 case 0x02:
9dcb0ba4 824 reg_xys = "s";
7b4ae824
JD
825 break;
826 }
827
828 operand_separator (info);
9dcb0ba4 829 (*info->fprintf_func) (info->stream, "%s", reg_xys);
7b4ae824
JD
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
9dcb0ba4 843 char *reg_xys = NULL;
7b4ae824
JD
844 switch (byte & 0x03)
845 {
846 case 0x00:
9dcb0ba4 847 reg_xys = "x";
7b4ae824
JD
848 break;
849 case 0x01:
9dcb0ba4 850 reg_xys = "y";
7b4ae824
JD
851 break;
852 case 0x02:
9dcb0ba4 853 reg_xys = "s";
7b4ae824
JD
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);
9dcb0ba4 864 (*info->fprintf_func) (info->stream, "%s, (%d,%s)", reg_xys, v, reg_xys);
7b4ae824
JD
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
f4107842
JD
1680 /* The NXP documentation is vague about BM_RESERVED0 and BM_RESERVED1,
1681 and contains obvious typos.
1682 However the Freescale tools and experiments with the chip itself
1683 seem to indicate that they behave like BM_REG_IMM and BM_OPR_REG
1684 respectively. */
1685
7b4ae824
JD
1686enum BM_MODE {
1687 BM_REG_IMM,
1688 BM_RESERVED0,
1689 BM_OPR_B,
1690 BM_OPR_W,
1691 BM_OPR_L,
1692 BM_OPR_REG,
1693 BM_RESERVED1
1694};
1695
1696struct bm
1697{
1698 uint8_t mask;
1699 uint8_t value;
1700 enum BM_MODE mode;
1701};
1702
1703static const struct bm bm_table[] = {
1704 { 0xC6, 0x04, BM_REG_IMM},
1705 { 0x84, 0x00, BM_REG_IMM},
1706 { 0x06, 0x06, BM_REG_IMM},
1707 { 0xC6, 0x44, BM_RESERVED0},
1708 // 00
1709 { 0x8F, 0x80, BM_OPR_B},
1710 { 0x8E, 0x82, BM_OPR_W},
1711 { 0x8C, 0x88, BM_OPR_L},
1712
1713 { 0x83, 0x81, BM_OPR_REG},
1714 { 0x87, 0x84, BM_RESERVED1},
1715};
1716
1717static void
1718bm_decode (bfd_vma memaddr, struct disassemble_info* info)
1719{
1720 uint8_t bm;
1721 int status = read_memory (memaddr, &bm, 1, info);
1722 if (status < 0)
1723 return;
1724
1725 size_t i;
1726 enum BM_MODE mode = -1;
1727 for (i = 0; i < sizeof (bm_table) / sizeof (bm_table[0]); ++i)
1728 {
1729 const struct bm *bme = bm_table + i;
1730 if ((bm & bme->mask) == bme->value)
1731 {
1732 mode = bme->mode;
1733 break;
1734 }
1735 }
1736
1737 switch (mode)
1738 {
1739 case BM_REG_IMM:
f4107842 1740 case BM_RESERVED0:
7b4ae824
JD
1741 operand_separator (info);
1742 (*info->fprintf_func) (info->stream, "%s", registers[bm & 0x07].name);
1743 break;
1744 case BM_OPR_B:
1745 (*info->fprintf_func) (info->stream, ".%c", 'b');
1746 opr_decode (memaddr + 1, info);
1747 break;
1748 case BM_OPR_W:
1749 (*info->fprintf_func) (info->stream, ".%c", 'w');
1750 opr_decode (memaddr + 1, info);
1751 break;
1752 case BM_OPR_L:
1753 (*info->fprintf_func) (info->stream, ".%c", 'l');
1754 opr_decode (memaddr + 1, info);
1755 break;
1756 case BM_OPR_REG:
f4107842 1757 case BM_RESERVED1:
7b4ae824
JD
1758 {
1759 uint8_t xb;
1760 read_memory (memaddr + 1, &xb, 1, info);
1761 /* Don't emit a size suffix for register operands */
1762 if ((xb & 0xF8) != 0xB8)
1763 (*info->fprintf_func) (info->stream, ".%c", shift_size_table[(bm & 0x0c) >> 2]);
1764 opr_decode (memaddr + 1, info);
1765 }
1766 break;
7b4ae824
JD
1767 }
1768
1769 uint8_t imm = 0;
1770 operand_separator (info);
1771 switch (mode)
1772 {
1773 case BM_REG_IMM:
1774 {
f4107842 1775 imm = (bm & 0x38) >> 3;
7b4ae824
JD
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:
f4107842 1790 case BM_RESERVED1:
7b4ae824
JD
1791 (*info->fprintf_func) (info->stream, "%s", registers[(bm & 0x70) >> 4].name);
1792 break;
1793 case BM_RESERVED0:
7b4ae824
JD
1794 assert (0);
1795 break;
1796 }
1797}
1798
1799
1800static void
1801bm_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:
f4107842 1823 case BM_RESERVED0:
7b4ae824
JD
1824 break;
1825 case BM_OPR_B:
1826 (*info->fprintf_func) (info->stream, ".%c", 'b');
1827 break;
1828 case BM_OPR_W:
1829 (*info->fprintf_func) (info->stream, ".%c", 'w');
1830 break;
1831 case BM_OPR_L:
1832 (*info->fprintf_func) (info->stream, ".%c", 'l');
1833 break;
1834 case BM_OPR_REG:
f4107842 1835 case BM_RESERVED1:
7b4ae824
JD
1836 {
1837 uint8_t xb;
1838 read_memory (memaddr + 1, &xb, 1, info);
1839 /* Don't emit a size suffix for register operands */
1840 if ((xb & 0xF8) != 0xB8)
1841 (*info->fprintf_func) (info->stream, ".%c",
1842 shift_size_table[(bm & 0x0C) >> 2]);
1843 }
1844 break;
7b4ae824
JD
1845 }
1846
1847 int n = 1;
1848 switch (mode)
1849 {
1850 case BM_REG_IMM:
f4107842 1851 case BM_RESERVED0:
7b4ae824
JD
1852 operand_separator (info);
1853 (*info->fprintf_func) (info->stream, "%s", registers[bm & 0x07].name);
1854 break;
1855 case BM_OPR_B:
1856 case BM_OPR_W:
1857 case BM_OPR_L:
1858 opr_decode (memaddr + 1, info);
1859 n = 1 + opr_n_bytes (memaddr + 1, info);
1860 break;
1861 case BM_OPR_REG:
7b4ae824 1862 case BM_RESERVED1:
f4107842 1863 opr_decode (memaddr + 1, info);
7b4ae824
JD
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;
f4107842
JD
1882 case BM_RESERVED0:
1883 imm = (bm & 0x38) >> 3;
1884 (*info->fprintf_func) (info->stream, "#%d", imm);
1885 break;
7b4ae824
JD
1886 case BM_REG_IMM:
1887 imm = (bm & 0xF8) >> 3;
1888 (*info->fprintf_func) (info->stream, "#%d", imm);
1889 break;
7b4ae824 1890 case BM_OPR_REG:
f4107842 1891 case BM_RESERVED1:
7b4ae824
JD
1892 (*info->fprintf_func) (info->stream, "%s", registers[(bm & 0x70) >> 4].name);
1893 n += opr_n_bytes (memaddr + 1, info);
1894 break;
1895 }
1896
1897 rel_15_7 (memaddr + n, info, n + 1);
1898}
1899
1900static int
1901bm_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
1902{
1903 uint8_t bm;
1904 int status = read_memory (memaddr, &bm, 1, info);
1905 if (status < 0)
1906 return status;
1907
1908 size_t i;
1909 enum BM_MODE mode = -1;
1910 for (i = 0; i < sizeof (bm_table) / sizeof (bm_table[0]); ++i)
1911 {
1912 const struct bm *bme = bm_table + i;
1913 if ((bm & bme->mask) == bme->value)
1914 {
1915 mode = bme->mode;
1916 break;
1917 }
1918 }
1919
1920 int n = 2;
1921 switch (mode)
1922 {
1923 case BM_REG_IMM:
f4107842 1924 case BM_RESERVED0:
7b4ae824
JD
1925 break;
1926
1927 case BM_OPR_B:
1928 case BM_OPR_W:
1929 case BM_OPR_L:
1930 n += opr_n_bytes (memaddr + 1, info);
1931 break;
1932 case BM_OPR_REG:
f4107842 1933 case BM_RESERVED1:
7b4ae824
JD
1934 n += opr_n_bytes (memaddr + 1, info);
1935 break;
7b4ae824
JD
1936 }
1937
1938 return n;
1939}
1940
1941static int
1942bm_rel_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
1943{
1944 int n = 1 + bm_n_bytes (memaddr, info);
1945
1946 bfd_byte rb;
1947 int status = read_memory (memaddr + n - 2, &rb, 1, info);
1948 if (status != 0)
1949 return status;
1950
1951 if (rb & 0x80)
1952 n++;
1953
1954 return n;
1955}
1956
1957
1958\f
1959
1960
1961/* shift direction */
1962enum SB_DIR
1963 {
1964 SB_LEFT,
1965 SB_RIGHT
1966 };
1967
1968enum SB_TYPE
1969 {
1970 SB_ARITHMETIC,
1971 SB_LOGICAL
1972 };
1973
1974
1975enum SB_MODE
1976 {
1977 SB_REG_REG_N_EFF,
1978 SB_REG_REG_N,
1979 SB_REG_OPR_EFF,
1980 SB_ROT,
1981 SB_REG_OPR_OPR,
1982 SB_OPR_N
1983 };
1984
1985struct sb
1986{
1987 uint8_t mask;
1988 uint8_t value;
1989 enum SB_MODE mode;
1990};
1991
1992static const struct sb sb_table[] = {
1993 {0x30, 0x00, SB_REG_REG_N_EFF},
1994 {0x30, 0x10, SB_REG_REG_N},
1995 {0x34, 0x20, SB_REG_OPR_EFF},
1996 {0x34, 0x24, SB_ROT},
1997 {0x34, 0x30, SB_REG_OPR_OPR},
1998 {0x34, 0x34, SB_OPR_N},
1999};
2000
2001static int
2002shift_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
2003{
2004 bfd_byte sb;
2005 int status = read_memory (memaddr++, &sb, 1, info);
2006 if (status != 0)
2007 return status;
2008
2009 size_t i;
2010 enum SB_MODE mode = -1;
2011 for (i = 0; i < sizeof (sb_table) / sizeof (sb_table[0]); ++i)
2012 {
2013 const struct sb *sbe = sb_table + i;
2014 if ((sb & sbe->mask) == sbe->value)
2015 mode = sbe->mode;
2016 }
2017
2018 switch (mode)
2019 {
2020 case SB_REG_REG_N_EFF:
2021 return 2;
2022 break;
2023 case SB_REG_OPR_EFF:
2024 case SB_ROT:
2025 return 2 + opr_n_bytes (memaddr, info);
2026 break;
2027 case SB_REG_OPR_OPR:
2028 {
2029 int opr1 = opr_n_bytes (memaddr, info);
2030 int opr2 = 0;
2031 if ((sb & 0x30) != 0x20)
2032 opr2 = opr_n_bytes (memaddr + opr1, info);
2033 return 2 + opr1 + opr2;
2034 }
2035 break;
2036 default:
2037 return 3;
2038 }
2039
2040 /* not reached */
2041 return -1;
2042}
2043\f
2044
2045static int
2046mov_imm_opr_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
2047{
2048 bfd_byte byte;
2049 int status = read_memory (memaddr - 1, &byte, 1, info);
2050 if (status < 0)
2051 return status;
2052
2053 int size = byte - 0x0c + 1;
2054
2055 return size + opr_n_bytes (memaddr + size, info) + 1;
2056}
2057
2058static void
2059mov_imm_opr (bfd_vma memaddr, struct disassemble_info* info)
2060{
2061 bfd_byte byte;
2062 int status = read_memory (memaddr - 1, &byte, 1, info);
2063 if (status < 0)
2064 return ;
2065
2066 int size = byte - 0x0c + 1;
2067 uint32_t imm = decode_signed_value (memaddr, info, size);
2068
2069 operand_separator (info);
2070 (*info->fprintf_func) (info->stream, "#%d", imm);
2071 opr_decode (memaddr + size, info);
2072}
2073
2074\f
2075
2076static void
2077ld_18bit_decode (bfd_vma memaddr, struct disassemble_info* info)
2078{
2079 size_t size = 3;
2080 bfd_byte buffer[3];
2081 int status = read_memory (memaddr, buffer + 1, 2, info);
2082 if (status < 0)
2083 return ;
2084
2085
2086 status = read_memory (memaddr - 1, buffer, 1, info);
2087 if (status < 0)
2088 return ;
2089
2090 buffer[0] = (buffer[0] & 0x30) >> 4;
2091
2092 size_t i;
2093 uint32_t imm = 0;
2094 for (i = 0; i < size; ++i)
2095 {
2096 imm |= buffer[i] << (8 * (size - i - 1));
2097 }
2098
2099 operand_separator (info);
2100 (*info->fprintf_func) (info->stream, "#%d", imm);
2101}
2102
2103\f
2104
2105/* Loop Primitives */
2106
2107enum LP_MODE {
2108 LP_REG,
2109 LP_XY,
2110 LP_OPR
2111};
2112
2113struct lp
2114{
2115 uint8_t mask;
2116 uint8_t value;
2117 enum LP_MODE mode;
2118};
2119
2120static const struct lp lp_mode[] = {
2121 {0x08, 0x00, LP_REG},
2122 {0x0C, 0x08, LP_XY},
2123 {0x0C, 0x0C, LP_OPR},
2124};
2125
2126
2127static const char *lb_condition[] =
2128 {
2129 "ne", "eq", "pl", "mi", "gt", "le",
2130 "??", "??"
2131 };
2132
2133static int
2134loop_prim_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
2135{
2136 int mx = 0;
2137 uint8_t lb;
2138 read_memory (memaddr + mx++, &lb, 1, info);
2139
2140 enum LP_MODE mode = -1;
2141 size_t i;
2142 for (i = 0; i < sizeof (lp_mode) / sizeof (lp_mode[0]); ++i)
2143 {
2144 const struct lp *pb = lp_mode + i;
2145 if ((lb & pb->mask) == pb->value)
2146 {
2147 mode = pb->mode;
2148 break;
2149 }
2150 }
2151
2152 if (mode == LP_OPR)
2153 {
2154 mx += opr_n_bytes (memaddr + mx, info) ;
2155 }
2156
2157 uint8_t rb;
2158 read_memory (memaddr + mx++, &rb, 1, info);
2159 if (rb & 0x80)
2160 mx++;
2161
2162 return mx + 1;
2163}
2164
2165
2166\f
2167
2168static int
2169print_insn_exg_sex (bfd_vma memaddr, struct disassemble_info* info)
2170{
2171 uint8_t eb;
2172 int status = read_memory (memaddr, &eb, 1, info);
2173 if (status < 0)
2174 return -1;
2175
2176 const struct reg *first = &registers[(eb & 0xf0) >> 4];
2177 const struct reg *second = &registers[(eb & 0xf)];
2178
2179 if (first->bytes < second->bytes)
2180 (*info->fprintf_func) (info->stream, "sex");
2181 else
2182 (*info->fprintf_func) (info->stream, "exg");
2183
2184 operand_separator (info);
2185 (*info->fprintf_func) (info->stream, "%s", first->name);
2186 operand_separator (info);
2187 (*info->fprintf_func) (info->stream, "%s", second->name);
2188 return 0;
2189}
2190
2191
2192
2193static int
2194print_insn_loop_primitive (bfd_vma memaddr, struct disassemble_info* info)
2195{
2196 int offs = 1;
2197 uint8_t lb;
2198 int status = read_memory (memaddr, &lb, 1, info);
2199
2200 char mnemonic[7];
2201 int x = 0;
2202 mnemonic[x++] = (lb & 0x80) ? 'd' : 't';
2203 mnemonic[x++] = 'b';
2204 stpcpy (mnemonic + x, lb_condition [(lb & 0x70) >> 4]);
2205 x += 2;
2206
9dcb0ba4 2207 const char *reg_dxy = NULL;
7b4ae824
JD
2208 enum LP_MODE mode = -1;
2209 size_t i;
2210 for (i = 0; i < sizeof (lp_mode) / sizeof (lp_mode[0]); ++i)
2211 {
2212 const struct lp *pb = lp_mode + i;
2213 if ((lb & pb->mask) == pb->value)
2214 {
2215 mode = pb->mode;
2216 break;
2217 }
2218 }
2219
2220 switch (mode)
2221 {
2222 case LP_REG:
9dcb0ba4 2223 reg_dxy = registers [lb & 0x07].name;
7b4ae824
JD
2224 break;
2225 case LP_XY:
9dcb0ba4 2226 reg_dxy = (lb & 0x1) ? "y" : "x";
7b4ae824
JD
2227 break;
2228 case LP_OPR:
2229 mnemonic[x++] = '.';
2230 mnemonic[x++] = shift_size_table [lb & 0x03];
2231 offs += opr_n_bytes (memaddr + 1, info);
2232 break;
2233 }
2234
2235 mnemonic[x++] = '\0';
2236
2237 (*info->fprintf_func) (info->stream, "%s", mnemonic);
2238
2239 if (mode == LP_OPR)
2240 opr_decode (memaddr + 1, info);
2241 else
2242 {
2243 operand_separator (info);
9dcb0ba4 2244 (*info->fprintf_func) (info->stream, "%s", reg_dxy);
7b4ae824
JD
2245 }
2246
2247 rel_15_7 (memaddr + offs, info, offs + 1);
2248
2249 return status;
2250}
2251
2252
2253static int
2254print_insn_shift (bfd_vma memaddr, struct disassemble_info* info, uint8_t byte)
2255{
2256 size_t i;
2257 uint8_t sb;
2258 int status = read_memory (memaddr, &sb, 1, info);
2259 if (status < 0)
2260 return status;
2261
2262 enum SB_DIR dir = (sb & 0x40) ? SB_LEFT : SB_RIGHT;
2263 enum SB_TYPE type = (sb & 0x80) ? SB_ARITHMETIC : SB_LOGICAL;
2264 enum SB_MODE mode = -1;
2265 for (i = 0; i < sizeof (sb_table) / sizeof (sb_table[0]); ++i)
2266 {
2267 const struct sb *sbe = sb_table + i;
2268 if ((sb & sbe->mask) == sbe->value)
2269 mode = sbe->mode;
2270 }
2271
2272 char mnemonic[6];
2273 int x = 0;
2274 if (mode == SB_ROT)
2275 {
2276 mnemonic[x++] = 'r';
2277 mnemonic[x++] = 'o';
2278 }
2279 else
2280 {
2281 mnemonic[x++] = (type == SB_LOGICAL) ? 'l' : 'a';
2282 mnemonic[x++] = 's';
2283 }
2284
2285 mnemonic[x++] = (dir == SB_LEFT) ? 'l' : 'r';
2286
2287 switch (mode)
2288 {
2289 case SB_REG_OPR_EFF:
2290 case SB_ROT:
2291 case SB_REG_OPR_OPR:
2292 mnemonic[x++] = '.';
2293 mnemonic[x++] = shift_size_table[sb & 0x03];
2294 break;
2295 case SB_OPR_N:
2296 {
2297 uint8_t xb;
2298 read_memory (memaddr + 1, &xb, 1, info);
2299 /* The size suffix is not printed if the OPR operand refers
2300 directly to a register, because the size is implied by the
2301 size of that register. */
2302 if ((xb & 0xF8) != 0xB8)
2303 {
2304 mnemonic[x++] = '.';
2305 mnemonic[x++] = shift_size_table[sb & 0x03];
2306 }
2307 }
2308 break;
2309 default:
2310 break;
2311 };
2312
2313 mnemonic[x++] = '\0';
2314
2315 (*info->fprintf_func) (info->stream, "%s", mnemonic);
2316
2317 /* Destination register */
2318 switch (mode)
2319 {
2320 case SB_REG_REG_N_EFF:
2321 case SB_REG_REG_N:
2322 case SB_REG_OPR_EFF:
2323 case SB_REG_OPR_OPR:
2324 operand_separator (info);
2325 (*info->fprintf_func) (info->stream, "%s", registers[byte & 0x7].name);
2326 break;
2327
2328 case SB_ROT:
2329 opr_decode (memaddr + 1, info);
2330 break;
2331
2332 default:
2333 break;
2334 }
2335
2336 /* Source register */
2337 switch (mode)
2338 {
2339 case SB_REG_REG_N_EFF:
2340 case SB_REG_REG_N:
2341 operand_separator (info);
2342 (*info->fprintf_func) (info->stream, "%s", registers[sb & 0x7].name);
2343 break;
2344
2345 case SB_REG_OPR_OPR:
2346 opr_decode (memaddr + 1, info);
2347 break;
2348
2349 default:
2350 break;
2351 }
2352
2353 /* 3rd arg */
2354 switch (mode)
2355 {
2356 case SB_REG_OPR_EFF:
2357 case SB_OPR_N:
2358 opr_decode (memaddr + 1, info);
2359 break;
2360
2361 case SB_REG_REG_N:
2362 if (sb & 0x08)
2363 {
2364 operand_separator (info);
2365 if (byte & 0x10)
2366 {
2367 uint8_t xb;
2368 read_memory (memaddr + 1, &xb, 1, info);
2369 int shift = ((sb & 0x08) >> 3) | ((xb & 0x0f) << 1);
2370 (*info->fprintf_func) (info->stream, "#%d", shift);
2371 }
2372 else
2373 {
2374 (*info->fprintf_func) (info->stream, "%s:%d", __FILE__, __LINE__);
2375 }
2376 }
2377 else
2378 {
2379 opr_decode (memaddr + 1, info);
2380 }
2381 break;
2382 case SB_REG_OPR_OPR:
2383 {
2384 uint8_t xb;
2385 int n = opr_n_bytes (memaddr + 1, info);
2386 read_memory (memaddr + 1 + n, &xb, 1, info);
2387
2388 if ((xb & 0xF0) == 0x70)
2389 {
2390 int imm = xb & 0x0F;
2391 imm <<= 1;
2392 imm |= (sb & 0x08) >> 3;
2393 operand_separator (info);
2394 (*info->fprintf_func) (info->stream, "#%d", imm);
2395 }
2396 else
2397 {
2398 opr_decode (memaddr + 1 + n, info);
2399 }
2400 }
2401 break;
2402 default:
2403 break;
2404 }
2405
2406 switch (mode)
2407 {
2408 case SB_REG_REG_N_EFF:
2409 case SB_REG_OPR_EFF:
2410 case SB_OPR_N:
2411 operand_separator (info);
2412 (*info->fprintf_func) (info->stream, "#%d",
2413 (sb & 0x08) ? 2 : 1);
2414 break;
2415
2416 default:
2417 break;
2418 }
2419
2420 return 0;
2421}
2422
2423int
2424print_insn_s12z (bfd_vma memaddr, struct disassemble_info* info)
2425{
2426 bfd_byte byte;
2427 int status = read_memory (memaddr++, &byte, 1, info);
2428 if (status != 0)
2429 return status;
2430
2431 const struct opcode *opc2 = NULL;
2432 const struct opcode *opc = page1 + byte;
2433 if (opc->mnemonic)
2434 {
2435 (*info->fprintf_func) (info->stream, "%s", opc->mnemonic);
2436 }
2437 else
2438 {
2439 /* The special cases ... */
2440 switch (byte)
2441 {
2442 case PAGE2_PREBYTE:
2443 {
2444 bfd_byte byte2;
2445 read_memory (memaddr++, &byte2, 1, info);
2446 opc2 = page2 + byte2;
2447 if (opc2->mnemonic)
2448 {
2449 (*info->fprintf_func) (info->stream, "%s", opc2->mnemonic);
2450
2451 if (opc2->operands)
2452 {
2453 opc2->operands (memaddr, info);
2454 }
2455
2456 if (opc2->operands2)
2457 {
2458 opc2->operands2 (memaddr, info);
2459 }
2460 }
2461 else if (byte2 >= 0x08 && byte2 <= 0x1F)
2462 {
2463 bfd_byte bb;
2464 read_memory (memaddr, &bb, 1, info);
2465 if (bb & 0x80)
2466 (*info->fprintf_func) (info->stream, "bfins");
2467 else
2468 (*info->fprintf_func) (info->stream, "bfext");
2469
2470 enum BB_MODE mode = -1;
2471 size_t i;
2472 const struct opr_bb *bbs = 0;
2473 for (i = 0; i < sizeof (bb_modes) / sizeof (bb_modes[0]); ++i)
2474 {
2475 bbs = bb_modes + i;
2476 if ((bb & bbs->mask) == bbs->value)
2477 {
2478 mode = bbs->mode;
2479 break;
2480 }
2481 }
2482
2483 switch (mode)
2484 {
2485 case BB_REG_OPR_REG:
2486 case BB_REG_OPR_IMM:
2487 case BB_OPR_REG_REG:
2488 case BB_OPR_REG_IMM:
2489 {
2490 int size = (bb >> 2) & 0x03;
2491 (*info->fprintf_func) (info->stream, ".%c",
2492 shift_size_table [size]);
2493 }
2494 break;
2495 default:
2496 break;
2497 }
2498
2499 int reg1 = byte2 & 0x07;
2500 /* First operand */
2501 switch (mode)
2502 {
2503 case BB_REG_REG_REG:
2504 case BB_REG_REG_IMM:
2505 case BB_REG_OPR_REG:
2506 case BB_REG_OPR_IMM:
2507 operand_separator (info);
2508 (*info->fprintf_func) (info->stream, "%s",
2509 registers[reg1].name);
2510 break;
2511 case BB_OPR_REG_REG:
2512 opr_decode (memaddr + 1, info);
2513 break;
2514 case BB_OPR_REG_IMM:
2515 opr_decode (memaddr + 2, info);
2516 break;
2517 }
2518
2519 /* Second operand */
2520 switch (mode)
2521 {
2522 case BB_REG_REG_REG:
2523 case BB_REG_REG_IMM:
2524 {
2525 int reg_src = (bb >> 2) & 0x07;
2526 operand_separator (info);
2527 (*info->fprintf_func) (info->stream, "%s",
2528 registers[reg_src].name);
2529 }
2530 break;
2531 case BB_OPR_REG_REG:
2532 case BB_OPR_REG_IMM:
2533 {
2534 int reg_src = (byte2 & 0x07);
2535 operand_separator (info);
2536 (*info->fprintf_func) (info->stream, "%s",
2537 registers[reg_src].name);
2538 }
2539 break;
2540 case BB_REG_OPR_REG:
2541 opr_decode (memaddr + 1, info);
2542 break;
2543 case BB_REG_OPR_IMM:
2544 opr_decode (memaddr + 2, info);
2545 break;
2546 }
2547
2548 /* Third operand */
2549 operand_separator (info);
2550 switch (mode)
2551 {
2552 case BB_REG_REG_REG:
2553 case BB_OPR_REG_REG:
2554 case BB_REG_OPR_REG:
2555 {
2556 int reg_parm = bb & 0x03;
2557 (*info->fprintf_func) (info->stream, "%s",
2558 registers[reg_parm].name);
2559 }
2560 break;
2561 case BB_REG_REG_IMM:
2562 case BB_OPR_REG_IMM:
2563 case BB_REG_OPR_IMM:
2564 {
2565 bfd_byte i1;
2566 read_memory (memaddr + 1, &i1, 1, info);
2567 int offset = i1 & 0x1f;
2568 int width = bb & 0x03;
2569 width <<= 3;
2570 width |= i1 >> 5;
2571 (*info->fprintf_func) (info->stream, "#%d:%d", width, offset);
2572 }
2573 break;
2574 }
2575 }
2576 }
2577 break;
2578 case 0xae: /* EXG / SEX */
2579 status = print_insn_exg_sex (memaddr, info);
2580 break;
2581 case 0x0b: /* Loop Primitives TBcc and DBcc */
2582 status = print_insn_loop_primitive (memaddr, info);
2583 break;
2584 case 0x10: /* shift */
2585 case 0x11: /* shift */
2586 case 0x12: /* shift */
2587 case 0x13: /* shift */
2588 case 0x14: /* shift */
2589 case 0x15: /* shift */
2590 case 0x16: /* shift */
2591 case 0x17: /* shift */
2592 status = print_insn_shift (memaddr, info, byte);
2593 break;
2594 case 0x04: /* psh / pul */
2595 {
2596 read_memory (memaddr, &byte, 1, info);
2597 (*info->fprintf_func) (info->stream, (byte & 0x80) ? "pul" : "psh");
2598 int bit;
2599 if (byte & 0x40)
2600 {
2601 if ((byte & 0x3F) == 0)
2602 {
2603 operand_separator (info);
2604 (*info->fprintf_func) (info->stream, "%s", "ALL16b");
2605 }
2606 else
2607 for (bit = 5; bit >= 0; --bit)
2608 {
2609 if (byte & (0x1 << bit))
2610 {
2611 operand_separator (info);
2612 (*info->fprintf_func) (info->stream, "%s", oprregs2[bit]);
2613 }
2614 }
2615 }
2616 else
2617 {
2618 if ((byte & 0x3F) == 0)
2619 {
2620 operand_separator (info);
2621 (*info->fprintf_func) (info->stream, "%s", "ALL");
2622 }
2623 else
2624 for (bit = 5; bit >= 0; --bit)
2625 {
2626 if (byte & (0x1 << bit))
2627 {
2628 operand_separator (info);
2629 (*info->fprintf_func) (info->stream, "%s", oprregs1[bit]);
2630 }
2631 }
2632 }
2633 }
2634 break;
2635 default:
2636 operand_separator (info);
2637 (*info->fprintf_func) (info->stream, "???");
2638 break;
2639 }
2640 }
2641
2642 if (opc2 == NULL)
2643 {
2644 if (opc->operands)
2645 {
2646 opc->operands (memaddr, info);
2647 }
2648
2649 if (opc->operands2)
2650 {
2651 opc->operands2 (memaddr, info);
2652 }
2653 }
2654
2655 int n = 0;
2656
2657 /* Opcodes in page2 have an additional byte */
2658 if (opc2)
2659 n++;
2660
2661 if (opc2 && opc2->insn_bytes == 0)
2662 return n;
2663
2664 if (!opc2 && opc->insn_bytes == 0)
2665 return n;
2666
2667 if (opc2)
2668 n += opc2->insn_bytes (memaddr, info);
2669 else
2670 n += opc->insn_bytes (memaddr, info);
2671
2672 return n;
2673}