x86: Update disassembler for VexWIG
[external/binutils.git] / opcodes / s12z-dis.c
1 /* s12z-dis.c -- Freescale S12Z disassembly
2    Copyright (C) 2018 Free Software Foundation, Inc.
3
4    This file is part of the GNU opcodes library.
5
6    This library is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3, or (at your option)
9    any later version.
10
11    It is distributed in the hope that it will be useful, but WITHOUT
12    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14    License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19    MA 02110-1301, USA.  */
20
21 #include "sysdep.h"
22 #include <stdio.h>
23 #include <stdint.h>
24 #include <stdbool.h>
25 #include <assert.h>
26
27 #include "opcode/s12z.h"
28
29 #include "bfd.h"
30 #include "dis-asm.h"
31
32
33 #include "disassemble.h"
34
35 static int
36 read_memory (bfd_vma memaddr, bfd_byte* buffer, int size,
37              struct disassemble_info* info)
38 {
39   int status = (*info->read_memory_func) (memaddr, buffer, size, info);
40   if (status != 0)
41     {
42       (*info->memory_error_func) (status, memaddr, info);
43       return -1;
44     }
45   return 0;
46 }
47
48 typedef int (* insn_bytes_f) (bfd_vma memaddr,
49                               struct disassemble_info* info);
50
51 typedef void (*operands_f) (bfd_vma memaddr, struct disassemble_info* info);
52
53 enum OPR_MODE
54   {
55     OPR_IMMe4,
56     OPR_REG,
57     OPR_OFXYS,
58     OPR_XY_PRE_INC,
59     OPR_XY_POST_INC,
60     OPR_XY_PRE_DEC,
61     OPR_XY_POST_DEC,
62     OPR_S_PRE_DEC,
63     OPR_S_POST_INC,
64     OPR_REG_DIRECT,
65     OPR_REG_INDIRECT,
66     OPR_IDX_DIRECT,
67     OPR_IDX_INDIRECT,
68     OPR_EXT1,
69     OPR_IDX2_REG,
70     OPR_IDX3_DIRECT,
71     OPR_IDX3_INDIRECT,
72
73     OPR_EXT18,
74     OPR_IDX3_DIRECT_REG,
75     OPR_EXT3_DIRECT,
76     OPR_EXT3_INDIRECT
77   };
78
79 struct opr_pb
80 {
81   uint8_t mask;
82   uint8_t value;
83   int n_operands;
84   enum OPR_MODE mode;
85 };
86
87 static const  struct opr_pb opr_pb[] = {
88   {0xF0, 0x70, 1, OPR_IMMe4},
89   {0xF8, 0xB8, 1, OPR_REG},
90   {0xC0, 0x40, 1, OPR_OFXYS},
91   {0xEF, 0xE3, 1, OPR_XY_PRE_INC},
92   {0xEF, 0xE7, 1, OPR_XY_POST_INC},
93   {0xEF, 0xC3, 1, OPR_XY_PRE_DEC},
94   {0xEF, 0xC7, 1, OPR_XY_POST_DEC},
95   {0xFF, 0xFB, 1, OPR_S_PRE_DEC},
96   {0xFF, 0xFF, 1, OPR_S_POST_INC},
97   {0xC8, 0x88, 1, OPR_REG_DIRECT},
98   {0xE8, 0xC8, 1, OPR_REG_INDIRECT},
99
100   {0xCE, 0xC0, 2, OPR_IDX_DIRECT},
101   {0xCE, 0xC4, 2, OPR_IDX_INDIRECT},
102   {0xC0, 0x00, 2, OPR_EXT1},
103
104   {0xC8, 0x80, 3, OPR_IDX2_REG},
105   {0xFA, 0xF8, 3, OPR_EXT18},
106
107   {0xCF, 0xC2, 4, OPR_IDX3_DIRECT},
108   {0xCF, 0xC6, 4, OPR_IDX3_INDIRECT},
109
110   {0xF8, 0xE8, 4, OPR_IDX3_DIRECT_REG},
111   {0xFF, 0xFA, 4, OPR_EXT3_DIRECT},
112   {0xFF, 0xFE, 4, OPR_EXT3_INDIRECT},
113 };
114
115
116 /* Return the number of bytes in a OPR operand, including the XB postbyte.
117    It does not include any preceeding opcodes. */
118 static int
119 opr_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
120 {
121   bfd_byte xb;
122   int status = read_memory (memaddr, &xb, 1, info);
123   if (status < 0)
124     return status;
125
126   size_t i;
127   for (i = 0; i < sizeof (opr_pb) / sizeof (opr_pb[0]); ++i)
128     {
129       const struct opr_pb *pb = opr_pb + i;
130       if ((xb & pb->mask) == pb->value)
131         {
132           return pb->n_operands;
133         }
134     }
135
136   return 1;
137 }
138
139 static int
140 opr_n_bytes_p1 (bfd_vma memaddr, struct disassemble_info* info)
141 {
142   return 1 + opr_n_bytes (memaddr, info);
143 }
144
145 static int
146 opr_n_bytes2 (bfd_vma memaddr, struct disassemble_info* info)
147 {
148   int s = opr_n_bytes (memaddr, info);
149   s += opr_n_bytes (memaddr + s, info);
150   return s + 1;
151 }
152
153 enum BB_MODE
154   {
155     BB_REG_REG_REG,
156     BB_REG_REG_IMM,
157     BB_REG_OPR_REG,
158     BB_OPR_REG_REG,
159     BB_REG_OPR_IMM,
160     BB_OPR_REG_IMM
161   };
162
163 struct opr_bb
164 {
165   uint8_t mask;
166   uint8_t value;
167   int n_operands;
168   bool opr;
169   enum BB_MODE mode;
170 };
171
172 static const struct opr_bb bb_modes[] =
173   {
174     {0x60, 0x00, 2, false, BB_REG_REG_REG},
175     {0x60, 0x20, 3, false, BB_REG_REG_IMM},
176     {0x70, 0x40, 2, true,  BB_REG_OPR_REG},
177     {0x70, 0x50, 2, true,  BB_OPR_REG_REG},
178     {0x70, 0x60, 3, true,  BB_REG_OPR_IMM},
179     {0x70, 0x70, 3, true,  BB_OPR_REG_IMM}
180   };
181
182 static int
183 bfextins_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
184 {
185   bfd_byte bb;
186   int status = read_memory (memaddr, &bb, 1, info);
187   if (status < 0)
188     return status;
189
190   size_t i;
191   const struct opr_bb *bbs = 0;
192   for (i = 0; i < sizeof (bb_modes) / sizeof (bb_modes[0]); ++i)
193     {
194       bbs = bb_modes + i;
195       if ((bb & bbs->mask) == bbs->value)
196         {
197           break;
198         }
199     }
200
201   int n = bbs->n_operands;
202   if (bbs->opr)
203     n += opr_n_bytes (memaddr + n - 1, info);
204
205   return n;
206 }
207
208 static int
209 single (bfd_vma memaddr ATTRIBUTE_UNUSED,
210         struct disassemble_info* info ATTRIBUTE_UNUSED)
211 {
212   return 1;
213 }
214
215 static int
216 two (bfd_vma memaddr ATTRIBUTE_UNUSED,
217      struct disassemble_info* info ATTRIBUTE_UNUSED)
218 {
219   return 2;
220 }
221
222 static int
223 three (bfd_vma memaddr ATTRIBUTE_UNUSED,
224        struct disassemble_info* info ATTRIBUTE_UNUSED)
225 {
226   return 3;
227 }
228
229 static int
230 four (bfd_vma memaddr ATTRIBUTE_UNUSED,
231       struct disassemble_info* info ATTRIBUTE_UNUSED)
232 {
233   return 4;
234 }
235
236 static int
237 five (bfd_vma memaddr ATTRIBUTE_UNUSED,
238       struct disassemble_info* info ATTRIBUTE_UNUSED)
239 {
240   return 5;
241 }
242
243 static int
244 pcrel_15bit (bfd_vma memaddr, struct disassemble_info* info)
245 {
246   bfd_byte byte;
247   int status = read_memory (memaddr, &byte, 1, info);
248   if (status < 0)
249     return status;
250   return (byte & 0x80) ? 3 : 2;
251 }
252
253
254 \f
255
256 static void
257 operand_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
273 static void
274 imm1 (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
285 static void
286 trap_decode (bfd_vma memaddr, struct disassemble_info* info)
287 {
288   imm1 (memaddr - 1, info);
289 }
290
291
292 const 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
314 static char *
315 xys_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
336 static char *
337 xysp_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. */
360 static void
361 decode_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
384 static void ld_18bit_decode (bfd_vma memaddr, struct disassemble_info* info);
385
386 static void
387 ext24_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
407 static uint32_t
408 decode_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
434 static void
435 opr_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
707 static void
708 opr_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
715 static void
716 imm1234 (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 */
734 static void
735 reg_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 */
746 static void
747 reg_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
755 static void
756 imm1234_8base (bfd_vma memaddr, struct disassemble_info* info)
757 {
758   imm1234 (memaddr, info, 8);
759 }
760
761 static void
762 imm1234_0base (bfd_vma memaddr, struct disassemble_info* info)
763 {
764   imm1234 (memaddr, info, 0);
765 }
766
767 static void
768 tfr (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
782 static void
783 reg (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
794 static void
795 reg_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
806 static void
807 lea_reg_xys_opr (bfd_vma memaddr, struct disassemble_info* info)
808 {
809   bfd_byte byte;
810   int status = read_memory (memaddr - 1, &byte, 1, info);
811   if (status < 0)
812     return;
813
814   char *reg_xys = NULL;
815   switch (byte & 0x03)
816     {
817     case 0x00:
818       reg_xys = "x";
819       break;
820     case 0x01:
821       reg_xys = "y";
822       break;
823     case 0x02:
824       reg_xys = "s";
825       break;
826     }
827
828   operand_separator (info);
829   (*info->fprintf_func) (info->stream, "%s", reg_xys);
830   opr_decode (memaddr, info);
831 }
832
833
834
835 static void
836 lea_reg_xys (bfd_vma memaddr, struct disassemble_info* info)
837 {
838   bfd_byte byte;
839   int status = read_memory (memaddr - 1, &byte, 1, info);
840   if (status < 0)
841     return;
842
843   char *reg_xys = NULL;
844   switch (byte & 0x03)
845     {
846     case 0x00:
847       reg_xys = "x";
848       break;
849     case 0x01:
850       reg_xys = "y";
851       break;
852     case 0x02:
853       reg_xys = "s";
854       break;
855     }
856
857   status = read_memory (memaddr, &byte, 1, info);
858   if (status < 0)
859     return;
860
861   int8_t v = byte;
862
863   operand_separator (info);
864   (*info->fprintf_func) (info->stream, "%s, (%d,%s)", reg_xys, v, reg_xys);
865 }
866
867
868 /* PC Relative offsets of size 15 or 7 bits */
869 static void
870 rel_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 */
930 static void
931 decode_rel_15_7 (bfd_vma memaddr, struct disassemble_info* info)
932 {
933   rel_15_7 (memaddr, info, 1);
934 }
935
936 struct opcode
937 {
938   const char *mnemonic;
939   insn_bytes_f insn_bytes;
940   operands_f operands;
941   operands_f operands2;
942 };
943
944 static int shift_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
945 static int mov_imm_opr_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
946 static int loop_prim_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
947 static void mov_imm_opr (bfd_vma memaddr, struct disassemble_info* info);
948 static void bm_rel_decode (bfd_vma memaddr, struct disassemble_info* info);
949 static int bm_rel_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
950 static int mul_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
951 static void mul_decode (bfd_vma memaddr, struct disassemble_info* info);
952 static int bm_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
953 static void bm_decode (bfd_vma memaddr, struct disassemble_info* info);
954
955 static void
956 cmp_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
962 static void
963 sub_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
969 static void
970 sub_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
976 static const char shift_size_table[] = {
977   'b', 'w', 'p', 'l'
978 };
979
980 static 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
1240 static 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
1501 static const char *oprregs1[] =
1502   {
1503     "d3", "d2", "d1", "d0", "ccl", "cch"
1504   };
1505
1506 static const char *oprregs2[] =
1507   {
1508     "y", "x", "d7", "d6", "d5", "d4"
1509   };
1510
1511
1512 \f
1513
1514 enum MUL_MODE
1515   {
1516     MUL_REG_REG,
1517     MUL_REG_OPR,
1518     MUL_REG_IMM,
1519     MUL_OPR_OPR
1520   };
1521
1522 struct mb
1523 {
1524   uint8_t mask;
1525   uint8_t value;
1526   enum MUL_MODE mode;
1527 };
1528
1529 static 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
1543 static void
1544 mul_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
1633 static int
1634 mul_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
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
1686 enum 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
1696 struct bm
1697 {
1698   uint8_t mask;
1699   uint8_t value;
1700   enum BM_MODE mode;
1701 };
1702
1703 static 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
1717 static void
1718 bm_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:
1740     case BM_RESERVED0:
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:
1757     case BM_RESERVED1:
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;
1767     }
1768
1769   uint8_t imm = 0;
1770   operand_separator (info);
1771   switch (mode)
1772     {
1773     case BM_REG_IMM:
1774       {
1775         imm = (bm & 0x38) >> 3;
1776         (*info->fprintf_func) (info->stream, "#%d", imm);
1777       }
1778       break;
1779     case BM_OPR_L:
1780       imm |= (bm & 0x03) << 3;
1781       /* fallthrough */
1782     case BM_OPR_W:
1783       imm |= (bm & 0x01) << 3;
1784       /* fallthrough */
1785     case BM_OPR_B:
1786       imm |= (bm & 0x70) >> 4;
1787       (*info->fprintf_func) (info->stream, "#%d", imm);
1788       break;
1789     case BM_OPR_REG:
1790     case BM_RESERVED1:
1791       (*info->fprintf_func) (info->stream, "%s", registers[(bm & 0x70) >> 4].name);
1792       break;
1793     case BM_RESERVED0:
1794       assert (0);
1795       break;
1796     }
1797 }
1798
1799
1800 static void
1801 bm_rel_decode (bfd_vma memaddr, struct disassemble_info* info)
1802 {
1803   uint8_t bm;
1804   int status = read_memory (memaddr, &bm, 1, info);
1805   if (status < 0)
1806     return;
1807
1808   size_t i;
1809   enum BM_MODE mode = -1;
1810   for (i = 0; i < sizeof (bm_table) / sizeof (bm_table[0]); ++i)
1811     {
1812       const struct bm *bme = bm_table + i;
1813       if ((bm & bme->mask) == bme->value)
1814         {
1815           mode = bme->mode;
1816           break;
1817         }
1818     }
1819
1820   switch (mode)
1821     {
1822     case BM_REG_IMM:
1823     case BM_RESERVED0:
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:
1835     case BM_RESERVED1:
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;
1845     }
1846
1847   int n = 1;
1848   switch (mode)
1849     {
1850     case BM_REG_IMM:
1851     case BM_RESERVED0:
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:
1862     case BM_RESERVED1:
1863       opr_decode (memaddr + 1, info);
1864       break;
1865     }
1866
1867
1868   int imm = 0;
1869   operand_separator (info);
1870   switch (mode)
1871     {
1872     case BM_OPR_L:
1873       imm |= (bm & 0x02) << 3;
1874       /* fall through */
1875     case BM_OPR_W:
1876       imm |= (bm & 0x01) << 3;
1877       /* fall through */
1878     case BM_OPR_B:
1879       imm |= (bm & 0x70) >> 4;
1880       (*info->fprintf_func) (info->stream, "#%d", imm);
1881       break;
1882     case BM_RESERVED0:
1883       imm = (bm & 0x38) >> 3;
1884       (*info->fprintf_func) (info->stream, "#%d", imm);
1885       break;
1886     case BM_REG_IMM:
1887       imm = (bm & 0xF8) >> 3;
1888       (*info->fprintf_func) (info->stream, "#%d", imm);
1889       break;
1890     case BM_OPR_REG:
1891     case BM_RESERVED1:
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
1900 static int
1901 bm_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:
1924     case BM_RESERVED0:
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:
1933     case BM_RESERVED1:
1934       n += opr_n_bytes (memaddr + 1, info);
1935       break;
1936   }
1937
1938   return n;
1939 }
1940
1941 static int
1942 bm_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 */
1962 enum SB_DIR
1963   {
1964     SB_LEFT,
1965     SB_RIGHT
1966   };
1967
1968 enum SB_TYPE
1969   {
1970     SB_ARITHMETIC,
1971     SB_LOGICAL
1972   };
1973
1974
1975 enum 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
1985 struct sb
1986 {
1987   uint8_t mask;
1988   uint8_t value;
1989   enum SB_MODE mode;
1990 };
1991
1992 static 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
2001 static int
2002 shift_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
2045 static int
2046 mov_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
2058 static void
2059 mov_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
2076 static void
2077 ld_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
2107 enum LP_MODE {
2108   LP_REG,
2109   LP_XY,
2110   LP_OPR
2111 };
2112
2113 struct lp
2114 {
2115   uint8_t mask;
2116   uint8_t value;
2117   enum LP_MODE mode;
2118 };
2119
2120 static const struct lp lp_mode[] = {
2121   {0x08, 0x00, LP_REG},
2122   {0x0C, 0x08, LP_XY},
2123   {0x0C, 0x0C, LP_OPR},
2124 };
2125
2126
2127 static const char *lb_condition[] =
2128   {
2129     "ne", "eq", "pl", "mi", "gt", "le",
2130     "??", "??"
2131   };
2132
2133 static int
2134 loop_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
2168 static int
2169 print_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
2193 static int
2194 print_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
2207   const char *reg_dxy  = NULL;
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:
2223       reg_dxy = registers [lb & 0x07].name;
2224       break;
2225     case LP_XY:
2226       reg_dxy = (lb & 0x1) ? "y" : "x";
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);
2244       (*info->fprintf_func) (info->stream, "%s", reg_dxy);
2245     }
2246
2247   rel_15_7 (memaddr + offs, info, offs + 1);
2248
2249   return status;
2250 }
2251
2252
2253 static int
2254 print_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
2423 int
2424 print_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 }