]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - opcodes/v850-dis.c
Better make rule for arch/ files built for IPA
[thirdparty/binutils-gdb.git] / opcodes / v850-dis.c
CommitLineData
252b5132 1/* Disassemble V850 instructions.
2571583a 2 Copyright (C) 1996-2017 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 */
78c8d46c 453 fprintf (stderr, _("unknown operand shift: %x\n"), operand->shift);
47b0e7ad 454 abort ();
252b5132
RH
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 */
1cd986c5 465 case 0: fprintf (stderr, _("unknown reg: %d\n"), i ); abort ();
b34976b6 466 case -1: pc = 1; break;
252b5132
RH
467 }
468 }
469 }
470
471 info->fprintf_func (info->stream, "{");
47b0e7ad 472
1cd986c5 473 if (mask || pc)
252b5132
RH
474 {
475 if (mask)
476 {
477 unsigned int bit;
b34976b6 478 int shown_one = 0;
47b0e7ad 479
252b5132
RH
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
b34976b6 489 shown_one = 1;
47b0e7ad 490
48891606 491 info->fprintf_func (info->stream, "%s", v850_reg_names[first]);
47b0e7ad 492
252b5132
RH
493 for (bit++; bit < 32; bit++)
494 if ((mask & (1 << bit)) == 0)
495 break;
496
497 last = bit;
498
499 if (last > first + 1)
1cd986c5
NC
500 {
501 info->fprintf_func (info->stream, " - %s", v850_reg_names[ last - 1 ]);
502 }
252b5132
RH
503 }
504 }
47b0e7ad 505
252b5132
RH
506 if (pc)
507 info->fprintf_func (info->stream, "%sPC", mask ? ", " : "");
252b5132 508 }
47b0e7ad 509
252b5132
RH
510 info->fprintf_func (info->stream, "}");
511 }
252b5132 512 break;
47b0e7ad 513
78c8d46c
NC
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;
1cd986c5
NC
561
562 default:
563 print_value (operand->flags, memaddr, info, value);
252b5132 564 break;
47b0e7ad 565 }
252b5132 566
7d063384 567 if (square)
252b5132
RH
568 (*info->fprintf_func) (info->stream, "]");
569 }
570
252b5132
RH
571 /* All done. */
572 break;
573 }
1cd986c5 574 next_opcode:
252b5132
RH
575 op++;
576 }
577
1cd986c5 578 return match;
252b5132
RH
579}
580
47b0e7ad
NC
581int
582print_insn_v850 (bfd_vma memaddr, struct disassemble_info * info)
252b5132 583{
1cd986c5
NC
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;
78c8d46c
NC
612
613 case bfd_mach_v850e3v5:
614 target_processor = PROCESSOR_V850E3V5;
615 break;
1cd986c5 616 }
252b5132 617
252b5132 618 status = info->read_memory_func (memaddr, buffer, 2, info);
1cd986c5
NC
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)
252b5132 631 {
1cd986c5
NC
632 insn2 = bfd_getl16 (buffer);
633 /* fprintf (stderr, "insn2 0x%08lx\n", insn2); */
634 }
47b0e7ad 635
1cd986c5
NC
636 /* Special case. */
637 if (length == 0
78c8d46c 638 && ((target_processor & PROCESSOR_V850E2_UP) != 0))
1cd986c5
NC
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)
252b5132 654 {
1cd986c5
NC
655 length = 2;
656 code_length = 6;
657 }
658 }
252b5132 659
1cd986c5 660 if (length == 0
78c8d46c
NC
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))
1cd986c5
NC
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;
252b5132
RH
699 }
700 }
47b0e7ad 701
1cd986c5
NC
702 if (length == 0
703 && target_processor != PROCESSOR_V850)
252b5132 704 {
1cd986c5
NC
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
78c8d46c
NC
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
1cd986c5
NC
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 }
252b5132
RH
785 }
786
1cd986c5 787 return code_length;
252b5132 788}