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