gdb: Extend the comments in c-exp.y
[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 "bfd_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       else
382         (*info->fprintf_func) (info->stream, "%" BFD_VMA_FMT "d", addr);
383     }
384 }
385
386 static void ld_18bit_decode (bfd_vma memaddr, struct disassemble_info* info);
387
388 static void
389 ext24_decode (bfd_vma memaddr, struct disassemble_info* info)
390 {
391   uint8_t buffer[3];
392   int status = read_memory (memaddr, buffer, 3, info);
393   if (status < 0)
394     return;
395
396   int i;
397   uint32_t addr = 0;
398   for (i = 0; i < 3; ++i)
399     {
400       addr <<= 8;
401       addr |= buffer[i];
402     }
403
404   operand_separator (info);
405   decode_possible_symbol (addr, info);
406 }
407
408
409 static uint32_t
410 decode_signed_value (bfd_vma memaddr, struct disassemble_info* info, short size)
411 {
412   assert (size >0);
413   assert (size <= 4);
414   bfd_byte buffer[4];
415   if (0 > read_memory (memaddr, buffer, size, info))
416     {
417       return 0;
418     }
419
420   int i;
421   uint32_t value = 0;
422   for (i = 0; i < size; ++i)
423     {
424       value |= buffer[i] << (8 * (size - i - 1));
425     }
426
427   if (buffer[0] & 0x80)
428     {
429       /* Deal with negative values */
430       value -= 0x1UL << (size * 8);
431     }
432   return value;
433 }
434
435
436 static void
437 opr_decode (bfd_vma memaddr, struct disassemble_info* info)
438 {
439   bfd_byte postbyte;
440   int status = read_memory (memaddr, &postbyte, 1, info);
441   if (status < 0)
442     return;
443
444   enum OPR_MODE mode = -1;
445   size_t i;
446   for (i = 0; i < sizeof (opr_pb) / sizeof (opr_pb[0]); ++i)
447     {
448       const struct opr_pb *pb = opr_pb + i;
449       if ((postbyte & pb->mask) == pb->value)
450         {
451           mode = pb->mode;
452           break;
453         }
454     }
455
456   operand_separator (info);
457   switch (mode)
458     {
459     case OPR_IMMe4:
460       {
461         int n;
462         uint8_t x = (postbyte & 0x0F);
463         if (x == 0)
464           n = -1;
465         else
466           n = x;
467
468         (*info->fprintf_func) (info->stream, "#%d", n);
469         break;
470       }
471     case OPR_REG:
472       {
473         uint8_t x = (postbyte & 0x07);
474         (*info->fprintf_func) (info->stream, "%s", registers[x].name);
475         break;
476       }
477     case OPR_OFXYS:
478       {
479         const char *reg  = xys_from_postbyte (postbyte);
480         (*info->fprintf_func) (info->stream, "(%d,%s)", postbyte & 0x0F, reg);
481         break;
482       }
483     case OPR_REG_DIRECT:
484       {
485         (*info->fprintf_func) (info->stream, "(%s,%s)", registers[postbyte & 0x07].name,
486                                xys_from_postbyte (postbyte));
487         break;
488       }
489     case OPR_REG_INDIRECT:
490       {
491         (*info->fprintf_func) (info->stream, "[%s,%s]", registers[postbyte & 0x07].name,
492                                (postbyte & 0x10) ? "y": "x");
493         break;
494       }
495
496     case OPR_IDX_INDIRECT:
497       {
498         uint8_t x1;
499         read_memory (memaddr + 1, &x1, 1, info);
500         int idx = x1;
501
502         if (postbyte & 0x01)
503           {
504             /* Deal with negative values */
505             idx -= 0x1UL << 8;
506           }
507
508         (*info->fprintf_func) (info->stream, "[%d,%s]", idx,
509                                xysp_from_postbyte (postbyte));
510         break;
511       }
512
513     case OPR_IDX3_DIRECT:
514       {
515         uint8_t x[3];
516         read_memory (memaddr + 1, x, 3, info);
517         int idx = x[0] << 16 | x[1] << 8 | x[2];
518
519         if (x[0] & 0x80)
520           {
521             /* Deal with negative values */
522             idx -= 0x1UL << 24;
523           }
524
525         (*info->fprintf_func) (info->stream, "(%d,%s)", idx,
526                                xysp_from_postbyte (postbyte));
527         break;
528       }
529
530     case OPR_IDX3_DIRECT_REG:
531       {
532         uint8_t x[3];
533         read_memory (memaddr + 1, x, 3, info);
534         int idx = x[0] << 16 | x[1] << 8 | x[2];
535
536         if (x[0] & 0x80)
537           {
538             /* Deal with negative values */
539             idx -= 0x1UL << 24;
540           }
541
542         (*info->fprintf_func) (info->stream, "(%d,%s)", idx,
543                                registers[postbyte & 0x07].name);
544         break;
545       }
546
547     case OPR_IDX3_INDIRECT:
548       {
549         uint8_t x[3];
550         read_memory (memaddr + 1, x, 3, info);
551         int idx = x[0] << 16 | x[1] << 8 | x[2];
552
553         if (x[0] & 0x80)
554           {
555             /* Deal with negative values */
556             idx -= 0x1UL << 24;
557           }
558
559         (*info->fprintf_func) (info->stream, "[%d,%s]", idx,
560                                xysp_from_postbyte (postbyte));
561         break;
562       }
563
564     case OPR_IDX_DIRECT:
565       {
566         uint8_t x1;
567         read_memory (memaddr + 1, &x1, 1, info);
568         int idx = x1;
569
570         if (postbyte & 0x01)
571           {
572             /* Deal with negative values */
573             idx -= 0x1UL << 8;
574           }
575
576         (*info->fprintf_func) (info->stream, "(%d,%s)", idx,
577                                xysp_from_postbyte (postbyte));
578         break;
579       }
580
581     case OPR_IDX2_REG:
582       {
583         uint8_t x[2];
584         read_memory (memaddr + 1, x, 2, info);
585         uint32_t offset = x[1] | x[0] << 8 ;
586         offset |= (postbyte & 0x30) << 12;
587
588         (*info->fprintf_func) (info->stream, "(%d,%s)", offset,
589                                registers[postbyte & 0x07].name);
590         break;
591       }
592
593     case OPR_XY_PRE_INC:
594       {
595         (*info->fprintf_func) (info->stream, "(+%s)",
596                                (postbyte & 0x10) ? "y": "x");
597
598         break;
599       }
600     case OPR_XY_POST_INC:
601       {
602         (*info->fprintf_func) (info->stream, "(%s+)",
603                                (postbyte & 0x10) ? "y": "x");
604
605         break;
606       }
607     case OPR_XY_PRE_DEC:
608       {
609         (*info->fprintf_func) (info->stream, "(-%s)",
610                                (postbyte & 0x10) ? "y": "x");
611
612         break;
613       }
614     case OPR_XY_POST_DEC:
615       {
616         (*info->fprintf_func) (info->stream, "(%s-)",
617                                (postbyte & 0x10) ? "y": "x");
618
619         break;
620       }
621     case OPR_S_PRE_DEC:
622       {
623         (*info->fprintf_func) (info->stream, "(-s)");
624         break;
625       }
626     case OPR_S_POST_INC:
627       {
628         (*info->fprintf_func) (info->stream, "(s+)");
629         break;
630       }
631
632     case OPR_EXT18:
633       {
634         const size_t size = 2;
635         bfd_byte buffer[4];
636         status = read_memory (memaddr + 1, buffer, size, info);
637         if (status < 0)
638           return;
639
640         uint32_t ext18 = 0;
641         for (i = 0; i < size; ++i)
642           {
643             ext18 <<= 8;
644             ext18 |= buffer[i];
645           }
646
647         ext18 |= (postbyte & 0x01) << 16;
648         ext18 |= (postbyte & 0x04) << 15;
649
650         decode_possible_symbol (ext18, info);
651         break;
652       }
653
654     case OPR_EXT1:
655       {
656         uint8_t x1 = 0;
657         read_memory (memaddr + 1, &x1, 1, info);
658         int16_t addr;
659         addr = x1;
660         addr |= (postbyte & 0x3f) << 8;
661
662         decode_possible_symbol (addr, info);
663         break;
664       }
665
666     case OPR_EXT3_DIRECT:
667       {
668         const size_t size = 3;
669         bfd_byte buffer[4];
670         status = read_memory (memaddr + 1, buffer, size, info);
671         if (status < 0)
672           return;
673
674         uint32_t ext24 = 0;
675         for (i = 0; i < size; ++i)
676           {
677             ext24 |= buffer[i] << (8 * (size - i - 1));
678           }
679
680         decode_possible_symbol (ext24, info);
681         break;
682       }
683
684     case OPR_EXT3_INDIRECT:
685       {
686         const size_t size = 3;
687         bfd_byte buffer[4];
688         status = read_memory (memaddr + 1, buffer, size, info);
689         if (status < 0)
690           return;
691
692         uint32_t ext24 = 0;
693         for (i = 0; i < size; ++i)
694           {
695             ext24 |= buffer[i] << (8 * (size - i - 1));
696           }
697
698         (*info->fprintf_func) (info->stream, "[%d]", ext24);
699
700         break;
701       }
702
703     default:
704       (*info->fprintf_func) (info->stream, "Unknown OPR mode #0x%x (%d)", postbyte, mode);
705     }
706 }
707
708
709 static void
710 opr_decode2 (bfd_vma memaddr, struct disassemble_info* info)
711 {
712   int n = opr_n_bytes (memaddr, info);
713   opr_decode (memaddr, info);
714   opr_decode (memaddr + n, info);
715 }
716
717 static void
718 imm1234 (bfd_vma memaddr, struct disassemble_info* info, int base)
719 {
720   bfd_byte opcode;
721   int status = read_memory (memaddr - 1, &opcode, 1, info);
722   if (status < 0)
723     return;
724
725   opcode -= base;
726
727   int size = registers[opcode & 0xF].bytes;
728
729   uint32_t imm = decode_signed_value (memaddr, info, size);
730   operand_separator (info);
731   (*info->fprintf_func) (info->stream, "#%d", imm);
732 }
733
734
735 /* Special case of LD and CMP with register S and IMM operand */
736 static void
737 reg_s_imm (bfd_vma memaddr, struct disassemble_info* info)
738 {
739   operand_separator (info);
740   (*info->fprintf_func) (info->stream, "s");
741
742   uint32_t imm = decode_signed_value (memaddr, info, 3);
743   operand_separator (info);
744   (*info->fprintf_func) (info->stream, "#%d", imm);
745 }
746
747 /* Special case of LD, CMP and ST with register S and OPR operand */
748 static void
749 reg_s_opr (bfd_vma memaddr, struct disassemble_info* info)
750 {
751   operand_separator (info);
752   (*info->fprintf_func) (info->stream, "s");
753
754   opr_decode (memaddr, info);
755 }
756
757 static void
758 imm1234_8base (bfd_vma memaddr, struct disassemble_info* info)
759 {
760   imm1234 (memaddr, info, 8);
761 }
762
763 static void
764 imm1234_0base (bfd_vma memaddr, struct disassemble_info* info)
765 {
766   imm1234 (memaddr, info, 0);
767 }
768
769 static void
770 tfr (bfd_vma memaddr, struct disassemble_info* info)
771 {
772   bfd_byte byte;
773   int status = read_memory (memaddr, &byte, 1, info);
774   if (status < 0)
775     return;
776
777   operand_separator (info);
778   (*info->fprintf_func) (info->stream, "%s, %s",
779                          registers[byte >> 4].name,
780                          registers[byte & 0xF].name);
781 }
782
783
784 static void
785 reg (bfd_vma memaddr, struct disassemble_info* info)
786 {
787   bfd_byte byte;
788   int status = read_memory (memaddr - 1, &byte, 1, info);
789   if (status < 0)
790     return;
791
792   operand_separator (info);
793   (*info->fprintf_func) (info->stream, "%s", registers[byte & 0x07].name);
794 }
795
796 static void
797 reg_xy (bfd_vma memaddr, struct disassemble_info* info)
798 {
799   bfd_byte byte;
800   int status = read_memory (memaddr - 1, &byte, 1, info);
801   if (status < 0)
802     return;
803
804   operand_separator (info);
805   (*info->fprintf_func) (info->stream, "%s", (byte & 0x01) ? "y" : "x");
806 }
807
808 static void
809 lea_reg_xys_opr (bfd_vma memaddr, struct disassemble_info* info)
810 {
811   bfd_byte byte;
812   int status = read_memory (memaddr - 1, &byte, 1, info);
813   if (status < 0)
814     return;
815
816   char *reg_xys = NULL;
817   switch (byte & 0x03)
818     {
819     case 0x00:
820       reg_xys = "x";
821       break;
822     case 0x01:
823       reg_xys = "y";
824       break;
825     case 0x02:
826       reg_xys = "s";
827       break;
828     }
829
830   operand_separator (info);
831   (*info->fprintf_func) (info->stream, "%s", reg_xys);
832   opr_decode (memaddr, info);
833 }
834
835
836
837 static void
838 lea_reg_xys (bfd_vma memaddr, struct disassemble_info* info)
839 {
840   bfd_byte byte;
841   int status = read_memory (memaddr - 1, &byte, 1, info);
842   if (status < 0)
843     return;
844
845   char *reg_xys = NULL;
846   switch (byte & 0x03)
847     {
848     case 0x00:
849       reg_xys = "x";
850       break;
851     case 0x01:
852       reg_xys = "y";
853       break;
854     case 0x02:
855       reg_xys = "s";
856       break;
857     }
858
859   status = read_memory (memaddr, &byte, 1, info);
860   if (status < 0)
861     return;
862
863   int8_t v = byte;
864
865   operand_separator (info);
866   (*info->fprintf_func) (info->stream, "%s, (%d,%s)", reg_xys, v, reg_xys);
867 }
868
869
870 /* PC Relative offsets of size 15 or 7 bits */
871 static void
872 rel_15_7 (bfd_vma memaddr, struct disassemble_info* info, int offset)
873 {
874   bfd_byte upper;
875   int status = read_memory (memaddr, &upper, 1, info);
876   if (status < 0)
877     return;
878
879   bool rel_size = (upper & 0x80);
880
881   int16_t addr = upper;
882   if (rel_size)
883     {
884       /* 15 bits.  Get the next byte */
885       bfd_byte lower;
886       status = read_memory (memaddr + 1, &lower, 1, info);
887       if (status < 0)
888         return;
889
890       addr <<= 8;
891       addr |= lower;
892       addr &= 0x7FFF;
893
894       bool negative = (addr & 0x4000);
895       addr &= 0x3FFF;
896       if (negative)
897         addr = addr - 0x4000;
898     }
899   else
900     {
901       /* 7 bits. */
902       bool negative = (addr & 0x40);
903       addr &= 0x3F;
904       if (negative)
905         addr = addr - 0x40;
906     }
907
908   operand_separator (info);
909   if (!info->symbol_at_address_func (addr + memaddr - offset, info))
910     {
911       (*info->fprintf_func) (info->stream, "*%+d", addr);
912     }
913   else
914     {
915       asymbol *sym = NULL;
916       int i;
917       for (i = 0; i < info->symtab_size; ++i)
918         {
919           sym = info->symtab[i];
920           if (bfd_asymbol_value (sym) == addr + memaddr - offset)
921             {
922               break;
923             }
924         }
925       if (i < info->symtab_size)
926         (*info->fprintf_func) (info->stream, "%s", bfd_asymbol_name (sym));
927       else
928         (*info->fprintf_func) (info->stream, "*%+d", addr);
929     }
930 }
931
932
933 /* PC Relative offsets of size 15 or 7 bits */
934 static void
935 decode_rel_15_7 (bfd_vma memaddr, struct disassemble_info* info)
936 {
937   rel_15_7 (memaddr, info, 1);
938 }
939
940 struct opcode
941 {
942   const char *mnemonic;
943   insn_bytes_f insn_bytes;
944   operands_f operands;
945   operands_f operands2;
946 };
947
948 static int shift_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
949 static int mov_imm_opr_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
950 static int loop_prim_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
951 static void mov_imm_opr (bfd_vma memaddr, struct disassemble_info* info);
952 static void bm_rel_decode (bfd_vma memaddr, struct disassemble_info* info);
953 static int bm_rel_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
954 static int mul_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
955 static void mul_decode (bfd_vma memaddr, struct disassemble_info* info);
956 static int bm_n_bytes (bfd_vma memaddr, struct disassemble_info* info);
957 static void bm_decode (bfd_vma memaddr, struct disassemble_info* info);
958
959 static void
960 cmp_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
966 static void
967 sub_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
973 static void
974 sub_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
980 static const char shift_size_table[] = {
981   'b', 'w', 'p', 'l'
982 };
983
984 static 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
1244 static 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
1505 static const char *oprregs1[] =
1506   {
1507     "d3", "d2", "d1", "d0", "ccl", "cch"
1508   };
1509
1510 static const char *oprregs2[] =
1511   {
1512     "y", "x", "d7", "d6", "d5", "d4"
1513   };
1514
1515
1516 \f
1517
1518 enum MUL_MODE
1519   {
1520     MUL_REG_REG,
1521     MUL_REG_OPR,
1522     MUL_REG_IMM,
1523     MUL_OPR_OPR
1524   };
1525
1526 struct mb
1527 {
1528   uint8_t mask;
1529   uint8_t value;
1530   enum MUL_MODE mode;
1531 };
1532
1533 static 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
1547 static void
1548 mul_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
1637 static int
1638 mul_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
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
1690 enum 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
1700 struct bm
1701 {
1702   uint8_t mask;
1703   uint8_t value;
1704   enum BM_MODE mode;
1705 };
1706
1707 static 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
1721 static void
1722 bm_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:
1744     case BM_RESERVED0:
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:
1761     case BM_RESERVED1:
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;
1771     }
1772
1773   uint8_t imm = 0;
1774   operand_separator (info);
1775   switch (mode)
1776     {
1777     case BM_REG_IMM:
1778       {
1779         imm = (bm & 0x38) >> 3;
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:
1794     case BM_RESERVED1:
1795       (*info->fprintf_func) (info->stream, "%s", registers[(bm & 0x70) >> 4].name);
1796       break;
1797     case BM_RESERVED0:
1798       assert (0);
1799       break;
1800     }
1801 }
1802
1803
1804 static void
1805 bm_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:
1827     case BM_RESERVED0:
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:
1839     case BM_RESERVED1:
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;
1849     }
1850
1851   int n = 1;
1852   switch (mode)
1853     {
1854     case BM_REG_IMM:
1855     case BM_RESERVED0:
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:
1866     case BM_RESERVED1:
1867       opr_decode (memaddr + 1, info);
1868       break;
1869     }
1870
1871
1872   int imm = 0;
1873   operand_separator (info);
1874   switch (mode)
1875     {
1876     case BM_OPR_L:
1877       imm |= (bm & 0x02) << 3;
1878       /* fall through */
1879     case BM_OPR_W:
1880       imm |= (bm & 0x01) << 3;
1881       /* fall through */
1882     case BM_OPR_B:
1883       imm |= (bm & 0x70) >> 4;
1884       (*info->fprintf_func) (info->stream, "#%d", imm);
1885       break;
1886     case BM_RESERVED0:
1887       imm = (bm & 0x38) >> 3;
1888       (*info->fprintf_func) (info->stream, "#%d", imm);
1889       break;
1890     case BM_REG_IMM:
1891       imm = (bm & 0xF8) >> 3;
1892       (*info->fprintf_func) (info->stream, "#%d", imm);
1893       break;
1894     case BM_OPR_REG:
1895     case BM_RESERVED1:
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
1904 static int
1905 bm_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:
1928     case BM_RESERVED0:
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:
1937     case BM_RESERVED1:
1938       n += opr_n_bytes (memaddr + 1, info);
1939       break;
1940   }
1941
1942   return n;
1943 }
1944
1945 static int
1946 bm_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 */
1966 enum SB_DIR
1967   {
1968     SB_LEFT,
1969     SB_RIGHT
1970   };
1971
1972 enum SB_TYPE
1973   {
1974     SB_ARITHMETIC,
1975     SB_LOGICAL
1976   };
1977
1978
1979 enum SB_MODE
1980   {
1981     SB_REG_REG_N_EFF,
1982     SB_REG_REG_N,
1983     SB_REG_OPR_EFF,
1984     SB_ROT,
1985     SB_REG_OPR_OPR,
1986     SB_OPR_N
1987   };
1988
1989 struct sb
1990 {
1991   uint8_t mask;
1992   uint8_t value;
1993   enum SB_MODE mode;
1994 };
1995
1996 static const  struct sb sb_table[] = {
1997   {0x30, 0x00,     SB_REG_REG_N_EFF},
1998   {0x30, 0x10,     SB_REG_REG_N},
1999   {0x34, 0x20,     SB_REG_OPR_EFF},
2000   {0x34, 0x24,     SB_ROT},
2001   {0x34, 0x30,     SB_REG_OPR_OPR},
2002   {0x34, 0x34,     SB_OPR_N},
2003 };
2004
2005 static int
2006 shift_n_bytes (bfd_vma memaddr, struct disassemble_info* info)
2007 {
2008   bfd_byte sb;
2009   int status = read_memory (memaddr++, &sb, 1, info);
2010   if (status != 0)
2011     return status;
2012
2013   size_t i;
2014   enum SB_MODE mode = -1;
2015   for (i = 0; i < sizeof (sb_table) / sizeof (sb_table[0]); ++i)
2016     {
2017       const struct sb *sbe = sb_table + i;
2018       if ((sb & sbe->mask) == sbe->value)
2019         mode = sbe->mode;
2020     }
2021
2022   switch (mode)
2023     {
2024     case SB_REG_REG_N_EFF:
2025       return 2;
2026       break;
2027     case SB_REG_OPR_EFF:
2028     case SB_ROT:
2029         return 2 + opr_n_bytes (memaddr, info);
2030       break;
2031     case SB_REG_OPR_OPR:
2032       {
2033         int opr1 = opr_n_bytes (memaddr, info);
2034         int opr2 = 0;
2035         if ((sb & 0x30) != 0x20)
2036           opr2 = opr_n_bytes (memaddr + opr1, info);
2037         return 2 + opr1 + opr2;
2038       }
2039       break;
2040     default:
2041       return 3;
2042     }
2043
2044   /* not reached */
2045   return -1;
2046 }
2047 \f
2048
2049 static int
2050 mov_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
2062 static void
2063 mov_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
2080 static void
2081 ld_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
2111 enum LP_MODE {
2112   LP_REG,
2113   LP_XY,
2114   LP_OPR
2115 };
2116
2117 struct lp
2118 {
2119   uint8_t mask;
2120   uint8_t value;
2121   enum LP_MODE mode;
2122 };
2123
2124 static const struct lp lp_mode[] = {
2125   {0x08, 0x00, LP_REG},
2126   {0x0C, 0x08, LP_XY},
2127   {0x0C, 0x0C, LP_OPR},
2128 };
2129
2130
2131 static const char *lb_condition[] =
2132   {
2133     "ne", "eq", "pl", "mi", "gt", "le",
2134     "??", "??"
2135   };
2136
2137 static int
2138 loop_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
2172 static int
2173 print_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
2197 static int
2198 print_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
2211   const char *reg_dxy  = NULL;
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:
2227       reg_dxy = registers [lb & 0x07].name;
2228       break;
2229     case LP_XY:
2230       reg_dxy = (lb & 0x1) ? "y" : "x";
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);
2248       (*info->fprintf_func) (info->stream, "%s", reg_dxy);
2249     }
2250
2251   rel_15_7 (memaddr + offs, info, offs + 1);
2252
2253   return status;
2254 }
2255
2256
2257 static int
2258 print_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:
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       }
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
2433 int
2434 print_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 }