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