gas/
[external/binutils.git] / opcodes / v850-dis.c
1 /* Disassemble V850 instructions.
2    Copyright 1996-2013 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
22 #include "sysdep.h"
23 #include <stdio.h>
24 #include <string.h>
25 #include "opcode/v850.h"
26 #include "dis-asm.h"
27 #include "opintl.h"
28
29 static const char *const v850_reg_names[] =
30 {
31   "r0", "r1", "r2", "sp", "gp", "r5", "r6", "r7",
32   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
33   "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
34   "r24", "r25", "r26", "r27", "r28", "r29", "ep", "lp"
35 };
36
37 static const char *const v850_sreg_names[] =
38 {
39   "eipc/vip/mpm", "eipsw/mpc", "fepc/tid", "fepsw/ppa", "ecr/vmecr", "psw/vmtid",
40   "sr6/fpsr/vmadr/dcc", "sr7/fpepc/dc0",
41   "sr8/fpst/vpecr/dcv1", "sr9/fpcc/vptid", "sr10/fpcfg/vpadr/spal", "sr11/spau",
42   "sr12/vdecr/ipa0l", "eiic/vdtid/ipa0u", "feic/ipa1l", "dbic/ipa1u",
43   "ctpc/ipa2l", "ctpsw/ipa2u", "dbpc/ipa3l", "dbpsw/ipa3u", "ctbp/dpa0l",
44   "dir/dpa0u", "bpc/dpa0u", "asid/dpa1l",
45   "bpav/dpa1u", "bpam/dpa2l", "bpdv/dpa2u", "bpdm/dpa3l", "eiwr/dpa3u",
46   "fewr", "dbwr", "bsel"
47 };
48
49 static const char *const v850_cc_names[] =
50 {
51   "v", "c/l", "z", "nh", "s/n", "t", "lt", "le",
52   "nv", "nc/nl", "nz", "h", "ns/p", "sa", "ge", "gt"
53 };
54
55 static const char *const v850_float_cc_names[] =
56 {
57   "f/t", "un/or", "eq/neq", "ueq/ogl", "olt/uge", "ult/oge", "ole/ugt", "ule/ogt",
58   "sf/st", "ngle/gle", "seq/sne", "ngl/gl", "lt/nlt", "nge/ge", "le/nle", "ngt/gt"
59 };
60
61
62 static const char *const v850_vreg_names[] =
63 {
64   "vr0", "vr1", "vr2", "vr3", "vr4", "vr5", "vr6", "vr7", "vr8", "vr9",
65   "vr10", "vr11", "vr12", "vr13", "vr14", "vr15", "vr16", "vr17", "vr18",
66   "vr19", "vr20", "vr21", "vr22", "vr23", "vr24", "vr25", "vr26", "vr27",
67   "vr28", "vr29", "vr30", "vr31"
68 };
69
70 static const char *const v850_cacheop_names[] =
71 {
72   "chbii", "cibii", "cfali", "cisti", "cildi", "chbid", "chbiwbd",
73   "chbwbd", "cibid", "cibiwbd", "cibwbd", "cfald", "cistd", "cildd"
74 };
75
76 static const int const v850_cacheop_codes[] =
77 {
78   0x00, 0x20, 0x40, 0x60, 0x61, 0x04, 0x06,
79   0x07, 0x24, 0x26, 0x27, 0x44, 0x64, 0x65, -1
80 };
81
82 static const char *const v850_prefop_names[] =
83 { "prefi", "prefd" };
84
85 static const int const v850_prefop_codes[] =
86 { 0x00, 0x04, -1};
87
88 static void
89 print_value (int flags,
90              bfd_vma memaddr,
91              struct disassemble_info *info,
92              long value)
93 {
94   if (flags & V850_PCREL)
95     {
96       bfd_vma addr = value + memaddr;
97       info->print_address_func (addr, info);
98     }
99   else if (flags & V850_OPERAND_DISP)
100     {
101       if (flags & V850_OPERAND_SIGNED)
102         {
103           info->fprintf_func (info->stream, "%ld", value);
104         }
105       else
106         {
107           info->fprintf_func (info->stream, "%lu", value);
108         }
109     }
110   else if ((flags & V850E_IMMEDIATE32)
111            || (flags & V850E_IMMEDIATE16HI))
112     {
113       info->fprintf_func (info->stream, "0x%lx", value);
114     }
115   else
116     {
117       if (flags & V850_OPERAND_SIGNED)
118         {
119           info->fprintf_func (info->stream, "%ld", value);
120         }
121       else
122         {
123           info->fprintf_func (info->stream, "%lu", value);
124         }
125     }
126 }
127
128 static long
129 get_operand_value (const struct v850_operand *operand,
130                    unsigned long insn,
131                    int bytes_read,
132                    bfd_vma memaddr,
133                    struct disassemble_info * info,
134                    bfd_boolean noerror,
135                    int *invalid)
136 {
137   long value;
138   bfd_byte buffer[4];
139
140   if ((operand->flags & V850E_IMMEDIATE16)
141       || (operand->flags & V850E_IMMEDIATE16HI))
142     {
143       int status = info->read_memory_func (memaddr + bytes_read, buffer, 2, info);
144
145       if (status == 0)
146         {
147           value = bfd_getl16 (buffer);
148
149           if (operand->flags & V850E_IMMEDIATE16HI)
150             value <<= 16;
151           else if (value & 0x8000)
152             value |= (-1L << 16);
153
154           return value;
155         }
156
157       if (!noerror)
158         info->memory_error_func (status, memaddr + bytes_read, info);
159
160       return 0;
161     }
162
163   if (operand->flags & V850E_IMMEDIATE23)
164     {
165       int status = info->read_memory_func (memaddr + 2, buffer, 4, info);
166
167       if (status == 0)
168         {
169           value = bfd_getl32 (buffer);
170
171           value = (operand->extract) (value, invalid);
172
173           return value;
174         }
175
176       if (!noerror)
177         info->memory_error_func (status, memaddr + bytes_read, info);
178
179       return 0;
180     }
181
182   if (operand->flags & V850E_IMMEDIATE32)
183     {
184       int status = info->read_memory_func (memaddr + bytes_read, buffer, 4, info);
185
186       if (status == 0)
187         {
188           bytes_read += 4;
189           value = bfd_getl32 (buffer);
190
191           return value;
192         }
193
194       if (!noerror)
195         info->memory_error_func (status, memaddr + bytes_read, info);
196
197       return 0;
198     }
199
200   if (operand->extract)
201     value = (operand->extract) (insn, invalid);
202   else
203     {
204       if (operand->bits == -1)
205         value = (insn & operand->shift);
206       else
207         value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
208
209       if (operand->flags & V850_OPERAND_SIGNED)
210         value = ((long)(value << (sizeof (long)*8 - operand->bits))
211                  >> (sizeof (long)*8 - operand->bits));
212     }
213
214   return value;
215 }
216
217
218 static int
219 disassemble (bfd_vma memaddr,
220              struct disassemble_info *info,
221              int bytes_read,
222              unsigned long insn)
223 {
224   struct v850_opcode *op = (struct v850_opcode *) v850_opcodes;
225   const struct v850_operand *operand;
226   int match = 0;
227   int target_processor;
228
229   switch (info->mach)
230     {
231     case 0:
232     default:
233       target_processor = PROCESSOR_V850;
234       break;
235
236     case bfd_mach_v850e:
237       target_processor = PROCESSOR_V850E;
238       break;
239
240     case bfd_mach_v850e1:
241       target_processor = PROCESSOR_V850E;
242       break;
243
244     case bfd_mach_v850e2:
245       target_processor = PROCESSOR_V850E2;
246       break;
247
248     case bfd_mach_v850e2v3:
249       target_processor = PROCESSOR_V850E2V3;
250       break;
251
252     case bfd_mach_v850e3v5:
253       target_processor = PROCESSOR_V850E3V5;
254       break;
255     }
256
257   /* If this is a two byte insn, then mask off the high bits.  */
258   if (bytes_read == 2)
259     insn &= 0xffff;
260
261   /* Find the opcode.  */
262   while (op->name)
263     {
264       if ((op->mask & insn) == op->opcode
265           && (op->processors & target_processor)
266           && !(op->processors & PROCESSOR_OPTION_ALIAS))
267         {
268           /* Code check start.  */
269           const unsigned char *opindex_ptr;
270           unsigned int opnum;
271           unsigned int memop;
272
273           for (opindex_ptr = op->operands, opnum = 1;
274                *opindex_ptr != 0;
275                opindex_ptr++, opnum++)
276             {
277               int invalid = 0;
278               long value;
279
280               operand = &v850_operands[*opindex_ptr];
281
282               value = get_operand_value (operand, insn, bytes_read, memaddr,
283                                          info, 1, &invalid);
284
285               if (invalid)
286                 goto next_opcode;
287
288               if ((operand->flags & V850_NOT_R0) && value == 0 && (op->memop) <=2)
289                 goto next_opcode;
290
291               if ((operand->flags & V850_NOT_SA) && value == 0xd)
292                 goto next_opcode;
293
294               if ((operand->flags & V850_NOT_IMM0) && value == 0)
295                 goto next_opcode;
296             }
297
298           /* Code check end.  */
299
300           match = 1;
301           (*info->fprintf_func) (info->stream, "%s\t", op->name);
302 #if 0
303           fprintf (stderr, "match: insn: %lx, mask: %lx, opcode: %lx, name: %s\n",
304                    insn, op->mask, op->opcode, op->name );
305 #endif
306
307           memop = op->memop;
308           /* Now print the operands.
309
310              MEMOP is the operand number at which a memory
311              address specification starts, or zero if this
312              instruction has no memory addresses.
313
314              A memory address is always two arguments.
315
316              This information allows us to determine when to
317              insert commas into the output stream as well as
318              when to insert disp[reg] expressions onto the
319              output stream.  */
320
321           for (opindex_ptr = op->operands, opnum = 1;
322                *opindex_ptr != 0;
323                opindex_ptr++, opnum++)
324             {
325               bfd_boolean square = FALSE;
326               long value;
327               int flag;
328               char *prefix;
329
330               operand = &v850_operands[*opindex_ptr];
331
332               value = get_operand_value (operand, insn, bytes_read, memaddr,
333                                          info, 0, 0);
334
335               /* The first operand is always output without any
336                  special handling.
337
338                  For the following arguments:
339
340                    If memop && opnum == memop + 1, then we need '[' since
341                    we're about to output the register used in a memory
342                    reference.
343
344                    If memop && opnum == memop + 2, then we need ']' since
345                    we just finished the register in a memory reference.  We
346                    also need a ',' before this operand.
347
348                    Else we just need a comma.
349
350                    We may need to output a trailing ']' if the last operand
351                    in an instruction is the register for a memory address.
352
353                    The exception (and there's always an exception) are the
354                    "jmp" insn which needs square brackets around it's only
355                    register argument, and the clr1/not1/set1/tst1 insns
356                    which [...] around their second register argument.  */
357
358               prefix = "";
359               if (operand->flags & V850_OPERAND_BANG)
360                 {
361                   prefix = "!";
362                 }
363               else if (operand->flags & V850_OPERAND_PERCENT)
364                 {
365                   prefix = "%";
366                 }
367
368               if (opnum == 1 && opnum == memop)
369                 {
370                   info->fprintf_func (info->stream, "%s[", prefix);
371                   square = TRUE;
372                 }
373               else if (   (strcmp ("stc.w", op->name) == 0
374                         || strcmp ("cache", op->name) == 0
375                         || strcmp ("pref",  op->name) == 0)
376                        && opnum == 2 && opnum == memop)
377                 {
378                   info->fprintf_func (info->stream, ", [");
379                   square = TRUE;
380                 }
381               else if (   (strcmp (op->name, "pushsp") == 0
382                         || strcmp (op->name, "popsp") == 0
383                         || strcmp (op->name, "dbpush" ) == 0)
384                        && opnum == 2)
385                 {
386                   info->fprintf_func (info->stream, "-");
387                 }
388               else if (opnum > 1
389                        && (v850_operands[*(opindex_ptr - 1)].flags
390                            & V850_OPERAND_DISP) != 0
391                        && opnum == memop)
392                 {
393                   info->fprintf_func (info->stream, "%s[", prefix);
394                   square = TRUE;
395                 }
396               else if (opnum == 2
397                        && (   op->opcode == 0x00e407e0 /* clr1 */
398                            || op->opcode == 0x00e207e0 /* not1 */
399                            || op->opcode == 0x00e007e0 /* set1 */
400                            || op->opcode == 0x00e607e0 /* tst1 */
401                            ))
402                 {
403                   info->fprintf_func (info->stream, ", %s[", prefix);
404                   square = TRUE;
405                 }               
406               else if (opnum > 1)
407                 info->fprintf_func (info->stream, ", %s", prefix);
408
409               /* Extract the flags, ignoring ones which do not
410                  effect disassembly output.  */
411               flag = operand->flags & (V850_OPERAND_REG
412                                        | V850_REG_EVEN
413                                        | V850_OPERAND_EP
414                                        | V850_OPERAND_SRG
415                                        | V850E_OPERAND_REG_LIST
416                                        | V850_OPERAND_CC
417                                        | V850_OPERAND_VREG
418                                        | V850_OPERAND_CACHEOP
419                                        | V850_OPERAND_PREFOP
420                                        | V850_OPERAND_FLOAT_CC);
421
422               switch (flag)
423                 {
424                 case V850_OPERAND_REG:
425                   info->fprintf_func (info->stream, "%s", v850_reg_names[value]);
426                   break;
427                 case (V850_OPERAND_REG|V850_REG_EVEN):
428                   info->fprintf_func (info->stream, "%s", v850_reg_names[value * 2]);
429                   break;
430                 case V850_OPERAND_EP:
431                   info->fprintf_func (info->stream, "ep");
432                   break;
433                 case V850_OPERAND_SRG:
434                   info->fprintf_func (info->stream, "%s", v850_sreg_names[value]);
435                   break;
436                 case V850E_OPERAND_REG_LIST:
437                   {
438                     static int list12_regs[32]   = { 30, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
439                                                      0,  0, 0, 0, 0, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24 };
440                     int *regs;
441                     int i;
442                     unsigned long int mask = 0;
443                     int pc = 0;
444
445                     switch (operand->shift)
446                       {
447                       case 0xffe00001: regs = list12_regs; break;
448                       default:
449                         /* xgettext:c-format */
450                         fprintf (stderr, _("unknown operand shift: %x\n"), operand->shift);
451                         abort ();
452                       }
453
454                     for (i = 0; i < 32; i++)
455                       {
456                         if (value & (1 << i))
457                           {
458                             switch (regs[ i ])
459                               {
460                               default: mask |= (1 << regs[ i ]); break;
461                                 /* xgettext:c-format */
462                               case 0:  fprintf (stderr, _("unknown reg: %d\n"), i ); abort ();
463                               case -1: pc = 1; break;
464                               }
465                           }
466                       }
467
468                     info->fprintf_func (info->stream, "{");
469
470                     if (mask || pc)
471                       {
472                         if (mask)
473                           {
474                             unsigned int bit;
475                             int shown_one = 0;
476
477                             for (bit = 0; bit < 32; bit++)
478                               if (mask & (1 << bit))
479                                 {
480                                   unsigned long int first = bit;
481                                   unsigned long int last;
482
483                                   if (shown_one)
484                                     info->fprintf_func (info->stream, ", ");
485                                   else
486                                     shown_one = 1;
487
488                                   info->fprintf_func (info->stream, "%s", v850_reg_names[first]);
489
490                                   for (bit++; bit < 32; bit++)
491                                     if ((mask & (1 << bit)) == 0)
492                                       break;
493
494                                   last = bit;
495
496                                   if (last > first + 1)
497                                     {
498                                       info->fprintf_func (info->stream, " - %s", v850_reg_names[ last - 1 ]);
499                                     }
500                                 }
501                           }
502
503                         if (pc)
504                           info->fprintf_func (info->stream, "%sPC", mask ? ", " : "");
505                       }
506
507                     info->fprintf_func (info->stream, "}");
508                   }
509                   break;
510
511                 case V850_OPERAND_CC:
512                   info->fprintf_func (info->stream, "%s", v850_cc_names[value]);
513                   break;
514
515                 case V850_OPERAND_FLOAT_CC:
516                   info->fprintf_func (info->stream, "%s", v850_float_cc_names[value]);
517                   break;
518
519                 case V850_OPERAND_CACHEOP:
520                   {
521                     int idx;
522
523                     for (idx = 0; v850_cacheop_codes[idx] != -1; idx++)
524                       {
525                         if (value == v850_cacheop_codes[idx])
526                           {
527                             info->fprintf_func (info->stream, "%s",
528                                                 v850_cacheop_names[idx]);
529                             goto MATCH_CACHEOP_CODE;
530                           }
531                       }
532                     info->fprintf_func (info->stream, "%d", (int) value);
533                   }
534                 MATCH_CACHEOP_CODE:
535                   break;
536
537                 case V850_OPERAND_PREFOP:
538                   {
539                     int idx;
540
541                     for (idx = 0; v850_prefop_codes[idx] != -1; idx++)
542                       {
543                         if (value == v850_prefop_codes[idx])
544                           {
545                             info->fprintf_func (info->stream, "%s",
546                               v850_prefop_names[idx]);
547                             goto MATCH_PREFOP_CODE;
548                           }
549                       }
550                     info->fprintf_func (info->stream, "%d", (int) value);
551                   }
552                 MATCH_PREFOP_CODE:
553                   break;
554
555                 case V850_OPERAND_VREG:
556                   info->fprintf_func (info->stream, "%s", v850_vreg_names[value]);
557                   break;
558
559                 default:
560                   print_value (operand->flags, memaddr, info, value);
561                   break;
562                 }
563
564               if (square)
565                 (*info->fprintf_func) (info->stream, "]");
566             }
567
568           /* All done. */
569           break;
570         }
571     next_opcode:
572       op++;
573     }
574
575   return match;
576 }
577
578 int
579 print_insn_v850 (bfd_vma memaddr, struct disassemble_info * info)
580 {
581   int status, status2, match;
582   bfd_byte buffer[8];
583   int length = 0, code_length = 0;
584   unsigned long insn = 0, insn2 = 0;
585   int target_processor;
586
587   switch (info->mach)
588     {
589     case 0:
590     default:
591       target_processor = PROCESSOR_V850;
592       break;
593
594     case bfd_mach_v850e:
595       target_processor = PROCESSOR_V850E;
596       break;
597
598     case bfd_mach_v850e1:
599       target_processor = PROCESSOR_V850E;
600       break;
601
602     case bfd_mach_v850e2:
603       target_processor = PROCESSOR_V850E2;
604       break;
605
606     case bfd_mach_v850e2v3:
607       target_processor = PROCESSOR_V850E2V3;
608       break;
609
610     case bfd_mach_v850e3v5:
611       target_processor = PROCESSOR_V850E3V5;
612       break;
613     }
614
615   status = info->read_memory_func (memaddr, buffer, 2, info);
616
617   if (status)
618     {
619       info->memory_error_func (status, memaddr, info);
620       return -1;
621     }
622
623   insn = bfd_getl16 (buffer);
624
625   status2 = info->read_memory_func (memaddr+2, buffer, 2 , info);
626
627   if (!status2)
628     {
629       insn2 = bfd_getl16 (buffer);
630       /* fprintf (stderr, "insn2 0x%08lx\n", insn2); */
631     }
632
633   /* Special case.  */
634   if (length == 0
635       && ((target_processor & PROCESSOR_V850E2_UP) != 0))
636     {
637       if ((insn & 0xffff) == 0x02e0             /* jr 32bit */
638           && !status2 && (insn2 & 0x1) == 0)
639         {
640           length = 2;
641           code_length = 6;
642         }
643       else if ((insn & 0xffe0) == 0x02e0        /* jarl 32bit */
644                && !status2 && (insn2 & 0x1) == 0)
645         {
646           length = 2;
647           code_length = 6;
648         }
649       else if ((insn & 0xffe0) == 0x06e0        /* jmp 32bit */
650                && !status2 && (insn2 & 0x1) == 0)
651         {
652           length = 2;
653           code_length = 6;
654         }
655     }
656
657   if (length == 0
658       && ((target_processor & PROCESSOR_V850E3V5_UP) != 0))
659     {
660       if (   ((insn & 0xffe0) == 0x07a0         /* ld.dw 23bit (v850e3v5) */
661               && !status2 && (insn2 & 0x000f) == 0x0009)
662           || ((insn & 0xffe0) == 0x07a0         /* st.dw 23bit (v850e3v5) */
663               && !status2 && (insn2 & 0x000f) == 0x000f))
664         {
665           length = 4;
666           code_length = 6;
667         }
668     }
669
670   if (length == 0
671       && ((target_processor & PROCESSOR_V850E2V3_UP) != 0))
672     {
673       if (((insn & 0xffe0) == 0x0780            /* ld.b 23bit */
674            && !status2 && (insn2 & 0x000f) == 0x0005)
675           || ((insn & 0xffe0) == 0x07a0         /* ld.bu 23bit */
676               && !status2 && (insn2 & 0x000f) == 0x0005)
677           || ((insn & 0xffe0) == 0x0780         /* ld.h 23bit */
678               && !status2 && (insn2 & 0x000f) == 0x0007)
679           || ((insn & 0xffe0) == 0x07a0         /* ld.hu 23bit */
680               && !status2 && (insn2 & 0x000f) == 0x0007)
681           || ((insn & 0xffe0) == 0x0780         /* ld.w 23bit */
682               && !status2 && (insn2 & 0x000f) == 0x0009))
683         {
684           length = 4;
685           code_length = 6;
686         }
687       else if (((insn & 0xffe0) == 0x0780       /* st.b 23bit */
688                && !status2 && (insn2 & 0x000f) == 0x000d)
689               || ((insn & 0xffe0) == 0x07a0     /* st.h 23bit */
690                   && !status2 && (insn2 & 0x000f) == 0x000d)
691               || ((insn & 0xffe0) == 0x0780     /* st.w 23bit */
692                   && !status2 && (insn2 & 0x000f) == 0x000f))
693         {
694           length = 4;
695           code_length = 6;
696         }
697     }
698
699   if (length == 0
700       && target_processor != PROCESSOR_V850)
701     {
702       if ((insn & 0xffe0) == 0x0620)            /* 32 bit MOV */
703         {
704           length = 2;
705           code_length = 6;
706         }
707       else if ((insn & 0xffc0) == 0x0780        /* prepare {list}, imm5, imm16<<16 */
708                && !status2 && (insn2 & 0x001f) == 0x0013)
709         {
710           length = 4;
711           code_length = 6;
712         }
713       else if ((insn & 0xffc0) == 0x0780        /* prepare {list}, imm5, imm16 */
714                && !status2 && (insn2 & 0x001f) == 0x000b)
715         {
716           length = 4;
717           code_length = 6;
718         }
719       else if ((insn & 0xffc0) == 0x0780        /* prepare {list}, imm5, imm32 */
720                && !status2 && (insn2 & 0x001f) == 0x001b)
721         {
722           length = 4;
723           code_length = 8;
724         }
725     }
726
727   if (length == 4
728       || (length == 0
729           && (insn & 0x0600) == 0x0600))
730     {
731       /* This is a 4 byte insn.  */
732       status = info->read_memory_func (memaddr, buffer, 4, info);
733       if (!status)
734         {
735           insn = bfd_getl32 (buffer);
736
737           if (!length)
738             length = code_length = 4;
739         }
740     }
741
742   if (code_length > length)
743     {
744       status = info->read_memory_func (memaddr + length, buffer, code_length - length, info);
745       if (status)
746         length = 0;
747     }
748
749   if (length == 0 && !status)
750     length = code_length = 2;
751
752   if (length == 2)
753     insn &= 0xffff;
754
755   /* when the last 2 bytes of section is 0xffff, length will be 0 and cause infinitive loop */
756   if (length == 0)
757     return -1;
758
759   match = disassemble (memaddr, info, length, insn);
760
761   if (!match)
762     {
763       int l = 0;
764
765       status = info->read_memory_func (memaddr, buffer, code_length, info);
766
767       while (l < code_length)
768         {
769           if (code_length - l == 2)
770             {
771               insn = bfd_getl16 (buffer + l) & 0xffff;
772               info->fprintf_func (info->stream, ".short\t0x%04lx", insn);
773               l += 2;
774             }
775           else
776             {
777               insn = bfd_getl32 (buffer + l);
778               info->fprintf_func (info->stream, ".long\t0x%08lx", insn);
779               l += 4;
780             }
781         }
782     }
783
784   return code_length;
785 }