]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - opcodes/v850-dis.c
gdb: Fix failure in gdb.base/complex-parts.exp for x86-32
[thirdparty/binutils-gdb.git] / opcodes / v850-dis.c
CommitLineData
252b5132 1/* Disassemble V850 instructions.
82704155 2 Copyright (C) 1996-2019 Free Software Foundation, Inc.
252b5132 3
9b201bb5
NC
4 This file is part of the GNU opcodes library.
5
6 This library is free software; you can redistribute it and/or modify
8ad30312 7 it under the terms of the GNU General Public License as published by
9b201bb5
NC
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
252b5132 10
9b201bb5
NC
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.
252b5132 15
8ad30312
NC
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
47b0e7ad
NC
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
252b5132
RH
20
21
0d8dfecf 22#include "sysdep.h"
df7b86aa 23#include <stdio.h>
78c8d46c 24#include <string.h>
47b0e7ad 25#include "opcode/v850.h"
88c1242d 26#include "disassemble.h"
252b5132
RH
27#include "opintl.h"
28
29static const char *const v850_reg_names[] =
1cd986c5
NC
30{
31 "r0", "r1", "r2", "sp", "gp", "r5", "r6", "r7",
47b0e7ad
NC
32 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
33 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
1cd986c5
NC
34 "r24", "r25", "r26", "r27", "r28", "r29", "ep", "lp"
35};
252b5132
RH
36
37static const char *const v850_sreg_names[] =
1cd986c5
NC
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};
252b5132
RH
48
49static const char *const v850_cc_names[] =
1cd986c5
NC
50{
51 "v", "c/l", "z", "nh", "s/n", "t", "lt", "le",
52 "nv", "nc/nl", "nz", "h", "ns/p", "sa", "ge", "gt"
53};
252b5132 54
1cd986c5 55static const char *const v850_float_cc_names[] =
252b5132 56{
1cd986c5
NC
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};
47b0e7ad 60
47b0e7ad 61
78c8d46c
NC
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
7903e530 76static const int v850_cacheop_codes[] =
78c8d46c
NC
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
7903e530 85static const int v850_prefop_codes[] =
78c8d46c
NC
86{ 0x00, 0x04, -1};
87
1cd986c5 88static void
78c8d46c
NC
89print_value (int flags,
90 bfd_vma memaddr,
91 struct disassemble_info *info,
92 long value)
1cd986c5
NC
93{
94 if (flags & V850_PCREL)
95 {
96 bfd_vma addr = value + memaddr;
41702d50
NC
97
98 if (flags & V850_INVERSE_PCREL)
99 addr = memaddr - value;
1cd986c5
NC
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 }
78c8d46c
NC
113 else if ((flags & V850E_IMMEDIATE32)
114 || (flags & V850E_IMMEDIATE16HI))
1cd986c5
NC
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}
47b0e7ad 130
1cd986c5
NC
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;
dd42f060 154 else if (value & 0x8000)
b6518b38 155 value |= (-1UL << 16);
1cd986c5
NC
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
78c8d46c
NC
222disassemble (bfd_vma memaddr,
223 struct disassemble_info *info,
224 int bytes_read,
225 unsigned long insn)
1cd986c5 226{
78c8d46c 227 struct v850_opcode *op = (struct v850_opcode *) v850_opcodes;
1cd986c5
NC
228 const struct v850_operand *operand;
229 int match = 0;
230 int target_processor;
252b5132
RH
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;
8ad30312
NC
242
243 case bfd_mach_v850e1:
1cd986c5
NC
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;
8ad30312 253 break;
78c8d46c
NC
254
255 case bfd_mach_v850e3v5:
256 target_processor = PROCESSOR_V850E3V5;
257 break;
252b5132 258 }
47b0e7ad 259
1cd986c5
NC
260 /* If this is a two byte insn, then mask off the high bits. */
261 if (bytes_read == 2)
262 insn &= 0xffff;
263
252b5132
RH
264 /* Find the opcode. */
265 while (op->name)
266 {
267 if ((op->mask & insn) == op->opcode
1cd986c5
NC
268 && (op->processors & target_processor)
269 && !(op->processors & PROCESSOR_OPTION_ALIAS))
252b5132 270 {
1cd986c5 271 /* Code check start. */
b34976b6
AM
272 const unsigned char *opindex_ptr;
273 unsigned int opnum;
274 unsigned int memop;
252b5132 275
1cd986c5
NC
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
78c8d46c
NC
285 value = get_operand_value (operand, insn, bytes_read, memaddr,
286 info, 1, &invalid);
1cd986c5
NC
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
252b5132
RH
303 match = 1;
304 (*info->fprintf_func) (info->stream, "%s\t", op->name);
1cd986c5
NC
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
252b5132
RH
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. */
47b0e7ad 323
252b5132
RH
324 for (opindex_ptr = op->operands, opnum = 1;
325 *opindex_ptr != 0;
326 opindex_ptr++, opnum++)
327 {
7d063384 328 bfd_boolean square = FALSE;
b34976b6
AM
329 long value;
330 int flag;
1cd986c5 331 char *prefix;
47b0e7ad 332
252b5132 333 operand = &v850_operands[*opindex_ptr];
47b0e7ad 334
78c8d46c
NC
335 value = get_operand_value (operand, insn, bytes_read, memaddr,
336 info, 0, 0);
252b5132
RH
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
47b0e7ad 354 in an instruction is the register for a memory address.
252b5132 355
04ee5257 356 The exception (and there's always an exception) are the
252b5132 357 "jmp" insn which needs square brackets around it's only
04ee5257
NC
358 register argument, and the clr1/not1/set1/tst1 insns
359 which [...] around their second register argument. */
360
1cd986c5
NC
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 }
252b5132 370
1cd986c5 371 if (opnum == 1 && opnum == memop)
7d063384
NC
372 {
373 info->fprintf_func (info->stream, "%s[", prefix);
374 square = TRUE;
375 }
78c8d46c
NC
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 }
1cd986c5 391 else if (opnum > 1
78c8d46c
NC
392 && (v850_operands[*(opindex_ptr - 1)].flags
393 & V850_OPERAND_DISP) != 0
1cd986c5 394 && opnum == memop)
7d063384
NC
395 {
396 info->fprintf_func (info->stream, "%s[", prefix);
397 square = TRUE;
398 }
04ee5257
NC
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;
7903e530 408 }
1cd986c5
NC
409 else if (opnum > 1)
410 info->fprintf_func (info->stream, ", %s", prefix);
411
78c8d46c
NC
412 /* Extract the flags, ignoring ones which do not
413 effect disassembly output. */
1cd986c5
NC
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
78c8d46c
NC
420 | V850_OPERAND_VREG
421 | V850_OPERAND_CACHEOP
422 | V850_OPERAND_PREFOP
1cd986c5 423 | V850_OPERAND_FLOAT_CC);
47b0e7ad 424
252b5132
RH
425 switch (flag)
426 {
78c8d46c
NC
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;
1cd986c5 439 case V850E_OPERAND_REG_LIST:
252b5132 440 {
1cd986c5
NC
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 };
b34976b6
AM
443 int *regs;
444 int i;
252b5132 445 unsigned long int mask = 0;
b34976b6 446 int pc = 0;
1cd986c5 447
252b5132
RH
448 switch (operand->shift)
449 {
450 case 0xffe00001: regs = list12_regs; break;
252b5132
RH
451 default:
452 /* xgettext:c-format */
a6743a54
AM
453 opcodes_error_handler (_("unknown operand shift: %x"),
454 operand->shift);
47b0e7ad 455 abort ();
252b5132
RH
456 }
457
458 for (i = 0; i < 32; i++)
459 {
460 if (value & (1 << i))
461 {
462 switch (regs[ i ])
463 {
a6743a54
AM
464 default:
465 mask |= (1 << regs[ i ]);
466 break;
467 case 0:
252b5132 468 /* xgettext:c-format */
a6743a54
AM
469 opcodes_error_handler (_("unknown reg: %d"), i);
470 abort ();
471 break;
472 case -1:
473 pc = 1;
474 break;
252b5132
RH
475 }
476 }
477 }
478
479 info->fprintf_func (info->stream, "{");
47b0e7ad 480
1cd986c5 481 if (mask || pc)
252b5132
RH
482 {
483 if (mask)
484 {
485 unsigned int bit;
b34976b6 486 int shown_one = 0;
47b0e7ad 487
252b5132
RH
488 for (bit = 0; bit < 32; bit++)
489 if (mask & (1 << bit))
490 {
491 unsigned long int first = bit;
492 unsigned long int last;
493
494 if (shown_one)
495 info->fprintf_func (info->stream, ", ");
496 else
b34976b6 497 shown_one = 1;
47b0e7ad 498
48891606 499 info->fprintf_func (info->stream, "%s", v850_reg_names[first]);
47b0e7ad 500
252b5132
RH
501 for (bit++; bit < 32; bit++)
502 if ((mask & (1 << bit)) == 0)
503 break;
504
505 last = bit;
506
507 if (last > first + 1)
1cd986c5
NC
508 {
509 info->fprintf_func (info->stream, " - %s", v850_reg_names[ last - 1 ]);
510 }
252b5132
RH
511 }
512 }
47b0e7ad 513
252b5132
RH
514 if (pc)
515 info->fprintf_func (info->stream, "%sPC", mask ? ", " : "");
252b5132 516 }
47b0e7ad 517
252b5132
RH
518 info->fprintf_func (info->stream, "}");
519 }
252b5132 520 break;
47b0e7ad 521
78c8d46c
NC
522 case V850_OPERAND_CC:
523 info->fprintf_func (info->stream, "%s", v850_cc_names[value]);
524 break;
525
526 case V850_OPERAND_FLOAT_CC:
527 info->fprintf_func (info->stream, "%s", v850_float_cc_names[value]);
528 break;
529
530 case V850_OPERAND_CACHEOP:
531 {
532 int idx;
533
534 for (idx = 0; v850_cacheop_codes[idx] != -1; idx++)
535 {
536 if (value == v850_cacheop_codes[idx])
537 {
538 info->fprintf_func (info->stream, "%s",
539 v850_cacheop_names[idx]);
540 goto MATCH_CACHEOP_CODE;
541 }
542 }
543 info->fprintf_func (info->stream, "%d", (int) value);
544 }
545 MATCH_CACHEOP_CODE:
546 break;
547
548 case V850_OPERAND_PREFOP:
549 {
550 int idx;
551
552 for (idx = 0; v850_prefop_codes[idx] != -1; idx++)
553 {
554 if (value == v850_prefop_codes[idx])
555 {
556 info->fprintf_func (info->stream, "%s",
557 v850_prefop_names[idx]);
558 goto MATCH_PREFOP_CODE;
559 }
560 }
561 info->fprintf_func (info->stream, "%d", (int) value);
562 }
563 MATCH_PREFOP_CODE:
564 break;
565
566 case V850_OPERAND_VREG:
567 info->fprintf_func (info->stream, "%s", v850_vreg_names[value]);
568 break;
1cd986c5
NC
569
570 default:
571 print_value (operand->flags, memaddr, info, value);
252b5132 572 break;
47b0e7ad 573 }
252b5132 574
7d063384 575 if (square)
252b5132
RH
576 (*info->fprintf_func) (info->stream, "]");
577 }
578
252b5132
RH
579 /* All done. */
580 break;
581 }
1cd986c5 582 next_opcode:
252b5132
RH
583 op++;
584 }
585
1cd986c5 586 return match;
252b5132
RH
587}
588
47b0e7ad
NC
589int
590print_insn_v850 (bfd_vma memaddr, struct disassemble_info * info)
252b5132 591{
1cd986c5
NC
592 int status, status2, match;
593 bfd_byte buffer[8];
594 int length = 0, code_length = 0;
595 unsigned long insn = 0, insn2 = 0;
596 int target_processor;
597
598 switch (info->mach)
599 {
600 case 0:
601 default:
602 target_processor = PROCESSOR_V850;
603 break;
604
605 case bfd_mach_v850e:
606 target_processor = PROCESSOR_V850E;
607 break;
608
609 case bfd_mach_v850e1:
610 target_processor = PROCESSOR_V850E;
611 break;
612
613 case bfd_mach_v850e2:
614 target_processor = PROCESSOR_V850E2;
615 break;
616
617 case bfd_mach_v850e2v3:
618 target_processor = PROCESSOR_V850E2V3;
619 break;
78c8d46c
NC
620
621 case bfd_mach_v850e3v5:
622 target_processor = PROCESSOR_V850E3V5;
623 break;
1cd986c5 624 }
252b5132 625
252b5132 626 status = info->read_memory_func (memaddr, buffer, 2, info);
1cd986c5
NC
627
628 if (status)
629 {
630 info->memory_error_func (status, memaddr, info);
631 return -1;
632 }
633
634 insn = bfd_getl16 (buffer);
635
636 status2 = info->read_memory_func (memaddr+2, buffer, 2 , info);
637
638 if (!status2)
252b5132 639 {
1cd986c5
NC
640 insn2 = bfd_getl16 (buffer);
641 /* fprintf (stderr, "insn2 0x%08lx\n", insn2); */
642 }
47b0e7ad 643
1cd986c5
NC
644 /* Special case. */
645 if (length == 0
78c8d46c 646 && ((target_processor & PROCESSOR_V850E2_UP) != 0))
1cd986c5
NC
647 {
648 if ((insn & 0xffff) == 0x02e0 /* jr 32bit */
649 && !status2 && (insn2 & 0x1) == 0)
650 {
651 length = 2;
652 code_length = 6;
653 }
654 else if ((insn & 0xffe0) == 0x02e0 /* jarl 32bit */
655 && !status2 && (insn2 & 0x1) == 0)
656 {
657 length = 2;
658 code_length = 6;
659 }
660 else if ((insn & 0xffe0) == 0x06e0 /* jmp 32bit */
661 && !status2 && (insn2 & 0x1) == 0)
252b5132 662 {
1cd986c5
NC
663 length = 2;
664 code_length = 6;
665 }
666 }
252b5132 667
1cd986c5 668 if (length == 0
78c8d46c
NC
669 && ((target_processor & PROCESSOR_V850E3V5_UP) != 0))
670 {
671 if ( ((insn & 0xffe0) == 0x07a0 /* ld.dw 23bit (v850e3v5) */
672 && !status2 && (insn2 & 0x000f) == 0x0009)
673 || ((insn & 0xffe0) == 0x07a0 /* st.dw 23bit (v850e3v5) */
674 && !status2 && (insn2 & 0x000f) == 0x000f))
675 {
676 length = 4;
677 code_length = 6;
678 }
679 }
680
681 if (length == 0
682 && ((target_processor & PROCESSOR_V850E2V3_UP) != 0))
1cd986c5
NC
683 {
684 if (((insn & 0xffe0) == 0x0780 /* ld.b 23bit */
685 && !status2 && (insn2 & 0x000f) == 0x0005)
686 || ((insn & 0xffe0) == 0x07a0 /* ld.bu 23bit */
687 && !status2 && (insn2 & 0x000f) == 0x0005)
688 || ((insn & 0xffe0) == 0x0780 /* ld.h 23bit */
689 && !status2 && (insn2 & 0x000f) == 0x0007)
690 || ((insn & 0xffe0) == 0x07a0 /* ld.hu 23bit */
691 && !status2 && (insn2 & 0x000f) == 0x0007)
692 || ((insn & 0xffe0) == 0x0780 /* ld.w 23bit */
693 && !status2 && (insn2 & 0x000f) == 0x0009))
694 {
695 length = 4;
696 code_length = 6;
697 }
698 else if (((insn & 0xffe0) == 0x0780 /* st.b 23bit */
699 && !status2 && (insn2 & 0x000f) == 0x000d)
700 || ((insn & 0xffe0) == 0x07a0 /* st.h 23bit */
701 && !status2 && (insn2 & 0x000f) == 0x000d)
702 || ((insn & 0xffe0) == 0x0780 /* st.w 23bit */
703 && !status2 && (insn2 & 0x000f) == 0x000f))
704 {
705 length = 4;
706 code_length = 6;
252b5132
RH
707 }
708 }
47b0e7ad 709
1cd986c5
NC
710 if (length == 0
711 && target_processor != PROCESSOR_V850)
252b5132 712 {
1cd986c5
NC
713 if ((insn & 0xffe0) == 0x0620) /* 32 bit MOV */
714 {
715 length = 2;
716 code_length = 6;
717 }
718 else if ((insn & 0xffc0) == 0x0780 /* prepare {list}, imm5, imm16<<16 */
719 && !status2 && (insn2 & 0x001f) == 0x0013)
720 {
721 length = 4;
722 code_length = 6;
723 }
724 else if ((insn & 0xffc0) == 0x0780 /* prepare {list}, imm5, imm16 */
725 && !status2 && (insn2 & 0x001f) == 0x000b)
726 {
727 length = 4;
728 code_length = 6;
729 }
730 else if ((insn & 0xffc0) == 0x0780 /* prepare {list}, imm5, imm32 */
731 && !status2 && (insn2 & 0x001f) == 0x001b)
732 {
733 length = 4;
734 code_length = 8;
735 }
736 }
737
738 if (length == 4
739 || (length == 0
740 && (insn & 0x0600) == 0x0600))
741 {
742 /* This is a 4 byte insn. */
743 status = info->read_memory_func (memaddr, buffer, 4, info);
744 if (!status)
745 {
746 insn = bfd_getl32 (buffer);
747
748 if (!length)
749 length = code_length = 4;
750 }
751 }
752
753 if (code_length > length)
754 {
755 status = info->read_memory_func (memaddr + length, buffer, code_length - length, info);
756 if (status)
757 length = 0;
758 }
759
760 if (length == 0 && !status)
761 length = code_length = 2;
762
763 if (length == 2)
764 insn &= 0xffff;
765
78c8d46c
NC
766 /* when the last 2 bytes of section is 0xffff, length will be 0 and cause infinitive loop */
767 if (length == 0)
768 return -1;
769
1cd986c5
NC
770 match = disassemble (memaddr, info, length, insn);
771
772 if (!match)
773 {
774 int l = 0;
775
776 status = info->read_memory_func (memaddr, buffer, code_length, info);
777
778 while (l < code_length)
779 {
780 if (code_length - l == 2)
781 {
782 insn = bfd_getl16 (buffer + l) & 0xffff;
783 info->fprintf_func (info->stream, ".short\t0x%04lx", insn);
784 l += 2;
785 }
786 else
787 {
788 insn = bfd_getl32 (buffer + l);
789 info->fprintf_func (info->stream, ".long\t0x%08lx", insn);
790 l += 4;
791 }
792 }
252b5132
RH
793 }
794
1cd986c5 795 return code_length;
252b5132 796}