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