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