1 /* Disassemble V850 instructions.
2 Copyright (C) 1996-2016 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 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 v850_prefop_codes[] =
86 { 0x00, 0x04, -1};
87
88 static void
print_value(int flags,bfd_vma memaddr,struct disassemble_info * info,long value)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
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
131 static long
get_operand_value(const struct v850_operand * operand,unsigned long insn,int bytes_read,bfd_vma memaddr,struct disassemble_info * info,bfd_boolean noerror,int * invalid)132 get_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
221 static int
disassemble(bfd_vma memaddr,struct disassemble_info * info,int bytes_read,unsigned long insn)222 disassemble (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
581 int
print_insn_v850(bfd_vma memaddr,struct disassemble_info * info)582 print_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