Change breakpoint::filter to be a unique_xmalloc_ptr
[external/binutils.git] / opcodes / m10300-dis.c
1 /* Disassemble MN10300 instructions.
2    Copyright (C) 1996-2019 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 "opcode/mn10300.h"
24 #include "disassemble.h"
25 #include "opintl.h"
26
27 #define HAVE_AM33_2 (info->mach == AM33_2)
28 #define HAVE_AM33   (info->mach == AM33 || HAVE_AM33_2)
29 #define HAVE_AM30   (info->mach == AM30)
30
31 static void
32 disassemble (bfd_vma memaddr,
33              struct disassemble_info *info,
34              unsigned long insn,
35              unsigned int size)
36 {
37   struct mn10300_opcode *op = (struct mn10300_opcode *) mn10300_opcodes;
38   const struct mn10300_operand *operand;
39   bfd_byte buffer[4];
40   unsigned long extension = 0;
41   int status, match = 0;
42
43   /* Find the opcode.  */
44   while (op->name)
45     {
46       int mysize, extra_shift;
47
48       if (op->format == FMT_S0)
49         mysize = 1;
50       else if (op->format == FMT_S1
51                || op->format == FMT_D0)
52         mysize = 2;
53       else if (op->format == FMT_S2
54                || op->format == FMT_D1)
55         mysize = 3;
56       else if (op->format == FMT_S4)
57         mysize = 5;
58       else if (op->format == FMT_D2)
59         mysize = 4;
60       else if (op->format == FMT_D3)
61         mysize = 5;
62       else if (op->format == FMT_D4)
63         mysize = 6;
64       else if (op->format == FMT_D6)
65         mysize = 3;
66       else if (op->format == FMT_D7 || op->format == FMT_D10)
67         mysize = 4;
68       else if (op->format == FMT_D8)
69         mysize = 6;
70       else if (op->format == FMT_D9)
71         mysize = 7;
72       else
73         mysize = 7;
74
75       if ((op->mask & insn) == op->opcode
76           && size == (unsigned int) mysize
77           && (op->machine == 0
78               || (op->machine == AM33_2 && HAVE_AM33_2)
79               || (op->machine == AM33 && HAVE_AM33)
80               || (op->machine == AM30 && HAVE_AM30)))
81         {
82           const unsigned char *opindex_ptr;
83           unsigned int nocomma;
84           int paren = 0;
85
86           if (op->format == FMT_D1 || op->format == FMT_S1)
87             extra_shift = 8;
88           else if (op->format == FMT_D2 || op->format == FMT_D4
89                    || op->format == FMT_S2 || op->format == FMT_S4
90                    || op->format == FMT_S6 || op->format == FMT_D5)
91             extra_shift = 16;
92           else if (op->format == FMT_D7
93                    || op->format == FMT_D8
94                    || op->format == FMT_D9)
95             extra_shift = 8;
96           else
97             extra_shift = 0;
98
99           if (size == 1 || size == 2)
100             extension = 0;
101
102           else if (size == 3
103                    && (op->format == FMT_D1
104                        || op->opcode == 0xdf0000
105                        || op->opcode == 0xde0000))
106             extension = 0;
107
108           else if (size == 3
109                    && op->format == FMT_D6)
110             extension = 0;
111
112           else if (size == 3)
113             {
114               insn &= 0xff0000;
115               status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
116               if (status != 0)
117                 {
118                   (*info->memory_error_func) (status, memaddr, info);
119                   return;
120                 }
121
122               insn |= bfd_getl16 (buffer);
123               extension = 0;
124             }
125           else if (size == 4
126                    && (op->opcode == 0xfaf80000
127                        || op->opcode == 0xfaf00000
128                        || op->opcode == 0xfaf40000))
129             extension = 0;
130
131           else if (size == 4
132                    && (op->format == FMT_D7
133                        || op->format == FMT_D10))
134             extension = 0;
135
136           else if (size == 4)
137             {
138               insn &= 0xffff0000;
139               status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
140               if (status != 0)
141                 {
142                   (*info->memory_error_func) (status, memaddr, info);
143                   return;
144                 }
145
146               insn |= bfd_getl16 (buffer);
147               extension = 0;
148             }
149           else if (size == 5 && op->opcode == 0xdc000000)
150             {
151               unsigned long temp = 0;
152
153               status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
154               if (status != 0)
155                 {
156                   (*info->memory_error_func) (status, memaddr, info);
157                   return;
158                 }
159               temp |= bfd_getl32 (buffer);
160
161               insn &= 0xff000000;
162               insn |= (temp & 0xffffff00) >> 8;
163               extension = temp & 0xff;
164             }
165           else if (size == 5 && op->format == FMT_D3)
166             {
167               status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
168               if (status != 0)
169                 {
170                   (*info->memory_error_func) (status, memaddr, info);
171                   return;
172                 }
173               insn &= 0xffff0000;
174               insn |= bfd_getl16 (buffer);
175
176               status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
177               if (status != 0)
178                 {
179                   (*info->memory_error_func) (status, memaddr, info);
180                   return;
181                 }
182               extension = *(unsigned char *) buffer;
183             }
184           else if (size == 5)
185             {
186               unsigned long temp = 0;
187
188               status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
189               if (status != 0)
190                 {
191                   (*info->memory_error_func) (status, memaddr, info);
192                   return;
193                 }
194               temp |= bfd_getl16 (buffer);
195
196               insn &= 0xff0000ff;
197               insn |= temp << 8;
198
199               status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
200               if (status != 0)
201                 {
202                   (*info->memory_error_func) (status, memaddr, info);
203                   return;
204                 }
205               extension = *(unsigned char *) buffer;
206             }
207           else if (size == 6 && op->format == FMT_D8)
208             {
209               insn &= 0xffffff00;
210               status = (*info->read_memory_func) (memaddr + 5, buffer, 1, info);
211               if (status != 0)
212                 {
213                   (*info->memory_error_func) (status, memaddr, info);
214                   return;
215                 }
216               insn |= *(unsigned char *) buffer;
217
218               status = (*info->read_memory_func) (memaddr + 3, buffer, 2, info);
219               if (status != 0)
220                 {
221                   (*info->memory_error_func) (status, memaddr, info);
222                   return;
223                 }
224               extension = bfd_getl16 (buffer);
225             }
226           else if (size == 6)
227             {
228               unsigned long temp = 0;
229
230               status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
231               if (status != 0)
232                 {
233                   (*info->memory_error_func) (status, memaddr, info);
234                   return;
235                 }
236               temp |= bfd_getl32 (buffer);
237
238               insn &= 0xffff0000;
239               insn |= (temp >> 16) & 0xffff;
240               extension = temp & 0xffff;
241             }
242           else if (size == 7 && op->format == FMT_D9)
243             {
244               insn &= 0xffffff00;
245               status = (*info->read_memory_func) (memaddr + 3, buffer, 4, info);
246               if (status != 0)
247                 {
248                   (*info->memory_error_func) (status, memaddr, info);
249                   return;
250                 }
251               extension = bfd_getl32 (buffer);
252               insn |= (extension & 0xff000000) >> 24;
253               extension &= 0xffffff;
254             }
255           else if (size == 7 && op->opcode == 0xdd000000)
256             {
257               unsigned long temp = 0;
258
259               status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
260               if (status != 0)
261                 {
262                   (*info->memory_error_func) (status, memaddr, info);
263                   return;
264                 }
265               temp |= bfd_getl32 (buffer);
266
267               insn &= 0xff000000;
268               insn |= (temp >> 8) & 0xffffff;
269               extension = (temp & 0xff) << 16;
270
271               status = (*info->read_memory_func) (memaddr + 5, buffer, 2, info);
272               if (status != 0)
273                 {
274                   (*info->memory_error_func) (status, memaddr, info);
275                   return;
276                 }
277               extension |= bfd_getb16 (buffer);
278             }
279           else if (size == 7)
280             {
281               unsigned long temp = 0;
282
283               status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
284               if (status != 0)
285                 {
286                   (*info->memory_error_func) (status, memaddr, info);
287                   return;
288                 }
289               temp |= bfd_getl32 (buffer);
290
291               insn &= 0xffff0000;
292               insn |= (temp >> 16) & 0xffff;
293               extension = (temp & 0xffff) << 8;
294
295               status = (*info->read_memory_func) (memaddr + 6, buffer, 1, info);
296               if (status != 0)
297                 {
298                   (*info->memory_error_func) (status, memaddr, info);
299                   return;
300                 }
301               extension |= *(unsigned char *) buffer;
302             }
303
304           match = 1;
305           (*info->fprintf_func) (info->stream, "%s\t", op->name);
306
307           /* Now print the operands.  */
308           for (opindex_ptr = op->operands, nocomma = 1;
309                *opindex_ptr != 0;
310                opindex_ptr++)
311             {
312               unsigned long value;
313
314               operand = &mn10300_operands[*opindex_ptr];
315
316               /* If this operand is a PLUS (autoincrement), then do not emit
317                  a comma before emitting the plus.  */
318               if ((operand->flags & MN10300_OPERAND_PLUS) != 0)
319                 nocomma = 1;
320
321               if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
322                 {
323                   unsigned long temp;
324
325                   value = insn & ((1 << operand->bits) - 1);
326                   value <<= (32 - operand->bits);
327                   temp = extension >> operand->shift;
328                   temp &= ((1 << (32 - operand->bits)) - 1);
329                   value |= temp;
330                   value = ((value ^ (((unsigned long) 1) << 31))
331                            - (((unsigned long) 1) << 31));
332                 }
333               else if ((operand->flags & MN10300_OPERAND_24BIT) != 0)
334                 {
335                   unsigned long temp;
336
337                   value = insn & ((1 << operand->bits) - 1);
338                   value <<= (24 - operand->bits);
339                   temp = extension >> operand->shift;
340                   temp &= ((1 << (24 - operand->bits)) - 1);
341                   value |= temp;
342                   if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
343                     value = ((value & 0xffffff) ^ 0x800000) - 0x800000;
344                 }
345               else if ((operand->flags & (MN10300_OPERAND_FSREG
346                                           | MN10300_OPERAND_FDREG)))
347                 {
348                   /* See m10300-opc.c just before #define FSM0 for an
349                      explanation of these variables.  Note that
350                      FMT-implied shifts are not taken into account for
351                      FP registers.  */
352                   unsigned long mask_low, mask_high;
353                   int shl_low, shr_high, shl_high;
354
355                   switch (operand->bits)
356                     {
357                     case 5:
358                       /* Handle regular FP registers.  */
359                       if (operand->shift >= 0)
360                         {
361                           /* This is an `m' register.  */
362                           shl_low = operand->shift;
363                           shl_high = 8 + (8 & shl_low) + (shl_low & 4) / 4;
364                         }
365                       else
366                         {
367                           /* This is an `n' register.  */
368                           shl_low = -operand->shift;
369                           shl_high = shl_low / 4;
370                         }
371                       mask_low = 0x0f;
372                       mask_high = 0x10;
373                       shr_high = 4;
374                       break;
375
376                     case 3:
377                       /* Handle accumulators.  */
378                       shl_low = -operand->shift;
379                       shl_high = 0;
380                       mask_low = 0x03;
381                       mask_high = 0x04;
382                       shr_high = 2;
383                       break;
384
385                     default:
386                       abort ();
387                     }
388                   value = ((((insn >> shl_high) << shr_high) & mask_high)
389                            | ((insn >> shl_low) & mask_low));
390                 }
391               else if ((operand->flags & MN10300_OPERAND_EXTENDED) != 0)
392                 value = ((extension >> (operand->shift))
393                          & ((1 << operand->bits) - 1));
394
395               else
396                 value = ((insn >> (operand->shift))
397                          & ((1 << operand->bits) - 1));
398
399               if ((operand->flags & MN10300_OPERAND_SIGNED) != 0
400                   /* These are properly extended by the code above.  */
401                   && ((operand->flags & MN10300_OPERAND_24BIT) == 0))
402                 value = ((value ^ (((unsigned long) 1) << (operand->bits - 1)))
403                          - (((unsigned long) 1) << (operand->bits - 1)));
404
405               if (!nocomma
406                   && (!paren
407                       || ((operand->flags & MN10300_OPERAND_PAREN) == 0)))
408                 (*info->fprintf_func) (info->stream, ",");
409
410               nocomma = 0;
411
412               if ((operand->flags & MN10300_OPERAND_DREG) != 0)
413                 {
414                   value = ((insn >> (operand->shift + extra_shift))
415                            & ((1 << operand->bits) - 1));
416                   (*info->fprintf_func) (info->stream, "d%d", (int) value);
417                 }
418
419               else if ((operand->flags & MN10300_OPERAND_AREG) != 0)
420                 {
421                   value = ((insn >> (operand->shift + extra_shift))
422                            & ((1 << operand->bits) - 1));
423                   (*info->fprintf_func) (info->stream, "a%d", (int) value);
424                 }
425
426               else if ((operand->flags & MN10300_OPERAND_SP) != 0)
427                 (*info->fprintf_func) (info->stream, "sp");
428
429               else if ((operand->flags & MN10300_OPERAND_PSW) != 0)
430                 (*info->fprintf_func) (info->stream, "psw");
431
432               else if ((operand->flags & MN10300_OPERAND_MDR) != 0)
433                 (*info->fprintf_func) (info->stream, "mdr");
434
435               else if ((operand->flags & MN10300_OPERAND_RREG) != 0)
436                 {
437                   value = ((insn >> (operand->shift + extra_shift))
438                            & ((1 << operand->bits) - 1));
439                   if (value < 8)
440                     (*info->fprintf_func) (info->stream, "r%d", (int) value);
441                   else if (value < 12)
442                     (*info->fprintf_func) (info->stream, "a%d", (int) value - 8);
443                   else
444                     (*info->fprintf_func) (info->stream, "d%d", (int) value - 12);
445                 }
446
447               else if ((operand->flags & MN10300_OPERAND_XRREG) != 0)
448                 {
449                   value = ((insn >> (operand->shift + extra_shift))
450                            & ((1 << operand->bits) - 1));
451                   if (value == 0)
452                     (*info->fprintf_func) (info->stream, "sp");
453                   else
454                     (*info->fprintf_func) (info->stream, "xr%d", (int) value);
455                 }
456
457               else if ((operand->flags & MN10300_OPERAND_FSREG) != 0)
458                 (*info->fprintf_func) (info->stream, "fs%d", (int) value);
459
460               else if ((operand->flags & MN10300_OPERAND_FDREG) != 0)
461                 (*info->fprintf_func) (info->stream, "fd%d", (int) value);
462
463               else if ((operand->flags & MN10300_OPERAND_FPCR) != 0)
464                 (*info->fprintf_func) (info->stream, "fpcr");
465
466               else if ((operand->flags & MN10300_OPERAND_USP) != 0)
467                 (*info->fprintf_func) (info->stream, "usp");
468
469               else if ((operand->flags & MN10300_OPERAND_SSP) != 0)
470                 (*info->fprintf_func) (info->stream, "ssp");
471
472               else if ((operand->flags & MN10300_OPERAND_MSP) != 0)
473                 (*info->fprintf_func) (info->stream, "msp");
474
475               else if ((operand->flags & MN10300_OPERAND_PC) != 0)
476                 (*info->fprintf_func) (info->stream, "pc");
477
478               else if ((operand->flags & MN10300_OPERAND_EPSW) != 0)
479                 (*info->fprintf_func) (info->stream, "epsw");
480
481               else if ((operand->flags & MN10300_OPERAND_PLUS) != 0)
482                 (*info->fprintf_func) (info->stream, "+");
483
484               else if ((operand->flags & MN10300_OPERAND_PAREN) != 0)
485                 {
486                   if (paren)
487                     (*info->fprintf_func) (info->stream, ")");
488                   else
489                     {
490                       (*info->fprintf_func) (info->stream, "(");
491                       nocomma = 1;
492                     }
493                   paren = !paren;
494                 }
495
496               else if ((operand->flags & MN10300_OPERAND_PCREL) != 0)
497                 (*info->print_address_func) ((long) value + memaddr, info);
498
499               else if ((operand->flags & MN10300_OPERAND_MEMADDR) != 0)
500                 (*info->print_address_func) (value, info);
501
502               else if ((operand->flags & MN10300_OPERAND_REG_LIST) != 0)
503                 {
504                   int comma = 0;
505
506                   (*info->fprintf_func) (info->stream, "[");
507                   if (value & 0x80)
508                     {
509                       (*info->fprintf_func) (info->stream, "d2");
510                       comma = 1;
511                     }
512
513                   if (value & 0x40)
514                     {
515                       if (comma)
516                         (*info->fprintf_func) (info->stream, ",");
517                       (*info->fprintf_func) (info->stream, "d3");
518                       comma = 1;
519                     }
520
521                   if (value & 0x20)
522                     {
523                       if (comma)
524                         (*info->fprintf_func) (info->stream, ",");
525                       (*info->fprintf_func) (info->stream, "a2");
526                       comma = 1;
527                     }
528
529                   if (value & 0x10)
530                     {
531                       if (comma)
532                         (*info->fprintf_func) (info->stream, ",");
533                       (*info->fprintf_func) (info->stream, "a3");
534                       comma = 1;
535                     }
536
537                   if (value & 0x08)
538                     {
539                       if (comma)
540                         (*info->fprintf_func) (info->stream, ",");
541                       (*info->fprintf_func) (info->stream, "other");
542                       comma = 1;
543                     }
544
545                   if (value & 0x04)
546                     {
547                       if (comma)
548                         (*info->fprintf_func) (info->stream, ",");
549                       (*info->fprintf_func) (info->stream, "exreg0");
550                       comma = 1;
551                     }
552                   if (value & 0x02)
553                     {
554                       if (comma)
555                         (*info->fprintf_func) (info->stream, ",");
556                       (*info->fprintf_func) (info->stream, "exreg1");
557                       comma = 1;
558                     }
559                   if (value & 0x01)
560                     {
561                       if (comma)
562                         (*info->fprintf_func) (info->stream, ",");
563                       (*info->fprintf_func) (info->stream, "exother");
564                       comma = 1;
565                     }
566                   (*info->fprintf_func) (info->stream, "]");
567                 }
568
569               else
570                 (*info->fprintf_func) (info->stream, "%ld", (long) value);
571             }
572           /* All done. */
573           break;
574         }
575       op++;
576     }
577
578   if (!match)
579     /* xgettext:c-format */
580     (*info->fprintf_func) (info->stream, _("unknown\t0x%04lx"), insn);
581 }
582
583 int
584 print_insn_mn10300 (bfd_vma memaddr, struct disassemble_info *info)
585 {
586   int status;
587   bfd_byte buffer[4];
588   unsigned long insn;
589   unsigned int consume;
590
591   /* First figure out how big the opcode is.  */
592   status = (*info->read_memory_func) (memaddr, buffer, 1, info);
593   if (status != 0)
594     {
595       (*info->memory_error_func) (status, memaddr, info);
596       return -1;
597     }
598   insn = *(unsigned char *) buffer;
599
600   /* These are one byte insns.  */
601   if ((insn & 0xf3) == 0x00
602       || (insn & 0xf0) == 0x10
603       || (insn & 0xfc) == 0x3c
604       || (insn & 0xf3) == 0x41
605       || (insn & 0xf3) == 0x40
606       || (insn & 0xfc) == 0x50
607       || (insn & 0xfc) == 0x54
608       || (insn & 0xf0) == 0x60
609       || (insn & 0xf0) == 0x70
610       || ((insn & 0xf0) == 0x80
611           && (insn & 0x0c) >> 2 != (insn & 0x03))
612       || ((insn & 0xf0) == 0x90
613           && (insn & 0x0c) >> 2 != (insn & 0x03))
614       || ((insn & 0xf0) == 0xa0
615           && (insn & 0x0c) >> 2 != (insn & 0x03))
616       || ((insn & 0xf0) == 0xb0
617           && (insn & 0x0c) >> 2 != (insn & 0x03))
618       || (insn & 0xff) == 0xcb
619       || (insn & 0xfc) == 0xd0
620       || (insn & 0xfc) == 0xd4
621       || (insn & 0xfc) == 0xd8
622       || (insn & 0xf0) == 0xe0
623       || (insn & 0xff) == 0xff)
624     {
625       consume = 1;
626     }
627
628   /* These are two byte insns.  */
629   else if ((insn & 0xf0) == 0x80
630            || (insn & 0xf0) == 0x90
631            || (insn & 0xf0) == 0xa0
632            || (insn & 0xf0) == 0xb0
633            || (insn & 0xfc) == 0x20
634            || (insn & 0xfc) == 0x28
635            || (insn & 0xf3) == 0x43
636            || (insn & 0xf3) == 0x42
637            || (insn & 0xfc) == 0x58
638            || (insn & 0xfc) == 0x5c
639            || ((insn & 0xf0) == 0xc0
640                && (insn & 0xff) != 0xcb
641                && (insn & 0xff) != 0xcc
642                && (insn & 0xff) != 0xcd)
643            || (insn & 0xff) == 0xf0
644            || (insn & 0xff) == 0xf1
645            || (insn & 0xff) == 0xf2
646            || (insn & 0xff) == 0xf3
647            || (insn & 0xff) == 0xf4
648            || (insn & 0xff) == 0xf5
649            || (insn & 0xff) == 0xf6)
650     {
651       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
652       if (status != 0)
653         {
654           (*info->memory_error_func) (status, memaddr, info);
655           return -1;
656         }
657       insn = bfd_getb16 (buffer);
658       consume = 2;
659     }
660
661   /* These are three byte insns.  */
662   else if ((insn & 0xff) == 0xf8
663            || (insn & 0xff) == 0xcc
664            || (insn & 0xff) == 0xf9
665            || (insn & 0xf3) == 0x01
666            || (insn & 0xf3) == 0x02
667            || (insn & 0xf3) == 0x03
668            || (insn & 0xfc) == 0x24
669            || (insn & 0xfc) == 0x2c
670            || (insn & 0xfc) == 0x30
671            || (insn & 0xfc) == 0x34
672            || (insn & 0xfc) == 0x38
673            || (insn & 0xff) == 0xde
674            || (insn & 0xff) == 0xdf
675            || (insn & 0xff) == 0xf9
676            || (insn & 0xff) == 0xcc)
677     {
678       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
679       if (status != 0)
680         {
681           (*info->memory_error_func) (status, memaddr, info);
682           return -1;
683         }
684       insn = bfd_getb16 (buffer);
685       insn <<= 8;
686       status = (*info->read_memory_func) (memaddr + 2, buffer, 1, info);
687       if (status != 0)
688         {
689           (*info->memory_error_func) (status, memaddr, info);
690           return -1;
691         }
692       insn |= *(unsigned char *) buffer;
693       consume = 3;
694     }
695
696   /* These are four byte insns.  */
697   else if ((insn & 0xff) == 0xfa
698            || (insn & 0xff) == 0xf7
699            || (insn & 0xff) == 0xfb)
700     {
701       status = (*info->read_memory_func) (memaddr, buffer, 4, info);
702       if (status != 0)
703         {
704           (*info->memory_error_func) (status, memaddr, info);
705           return -1;
706         }
707       insn = bfd_getb32 (buffer);
708       consume = 4;
709     }
710
711   /* These are five byte insns.  */
712   else if ((insn & 0xff) == 0xcd
713            || (insn & 0xff) == 0xdc)
714     {
715       status = (*info->read_memory_func) (memaddr, buffer, 4, info);
716       if (status != 0)
717         {
718           (*info->memory_error_func) (status, memaddr, info);
719           return -1;
720         }
721       insn = bfd_getb32 (buffer);
722       consume = 5;
723     }
724
725   /* These are six byte insns.  */
726   else if ((insn & 0xff) == 0xfd
727            || (insn & 0xff) == 0xfc)
728     {
729       status = (*info->read_memory_func) (memaddr, buffer, 4, info);
730       if (status != 0)
731         {
732           (*info->memory_error_func) (status, memaddr, info);
733           return -1;
734         }
735
736       insn = bfd_getb32 (buffer);
737       consume = 6;
738     }
739
740   /* Else its a seven byte insns (in theory).  */
741   else
742     {
743       status = (*info->read_memory_func) (memaddr, buffer, 4, info);
744       if (status != 0)
745         {
746           (*info->memory_error_func) (status, memaddr, info);
747           return -1;
748         }
749
750       insn = bfd_getb32 (buffer);
751       consume = 7;
752       /* Handle the 5-byte extended instruction codes.  */
753       if ((insn & 0xfff80000) == 0xfe800000)
754         consume = 5;
755     }
756
757   disassemble (memaddr, info, insn, consume);
758
759   return consume;
760 }