OSDN Git Service

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