Add support for V850E3V5 architecture
[deliverable/binutils-gdb.git] / opcodes / v850-dis.c
CommitLineData
252b5132 1/* Disassemble V850 instructions.
78c8d46c 2 Copyright 1996-2013 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"
252b5132
RH
26#include "dis-asm.h"
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
76static 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
82static const char *const v850_prefop_names[] =
83{ "prefi", "prefd" };
84
85static const int const v850_prefop_codes[] =
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;
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 }
78c8d46c
NC
110 else if ((flags & V850E_IMMEDIATE32)
111 || (flags & V850E_IMMEDIATE16HI))
1cd986c5
NC
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}
47b0e7ad 127
1cd986c5
NC
128static long
129get_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;
dd42f060
NC
151 else if (value & 0x8000)
152 value |= (-1L << 16);
1cd986c5
NC
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
218static int
78c8d46c
NC
219disassemble (bfd_vma memaddr,
220 struct disassemble_info *info,
221 int bytes_read,
222 unsigned long insn)
1cd986c5 223{
78c8d46c 224 struct v850_opcode *op = (struct v850_opcode *) v850_opcodes;
1cd986c5
NC
225 const struct v850_operand *operand;
226 int match = 0;
227 int target_processor;
252b5132
RH
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;
8ad30312
NC
239
240 case bfd_mach_v850e1:
1cd986c5
NC
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;
8ad30312 250 break;
78c8d46c
NC
251
252 case bfd_mach_v850e3v5:
253 target_processor = PROCESSOR_V850E3V5;
254 break;
252b5132 255 }
47b0e7ad 256
1cd986c5
NC
257 /* If this is a two byte insn, then mask off the high bits. */
258 if (bytes_read == 2)
259 insn &= 0xffff;
260
252b5132
RH
261 /* Find the opcode. */
262 while (op->name)
263 {
264 if ((op->mask & insn) == op->opcode
1cd986c5
NC
265 && (op->processors & target_processor)
266 && !(op->processors & PROCESSOR_OPTION_ALIAS))
252b5132 267 {
1cd986c5 268 /* Code check start. */
b34976b6
AM
269 const unsigned char *opindex_ptr;
270 unsigned int opnum;
271 unsigned int memop;
252b5132 272
1cd986c5
NC
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
78c8d46c
NC
282 value = get_operand_value (operand, insn, bytes_read, memaddr,
283 info, 1, &invalid);
1cd986c5
NC
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
252b5132
RH
300 match = 1;
301 (*info->fprintf_func) (info->stream, "%s\t", op->name);
1cd986c5
NC
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
252b5132
RH
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. */
47b0e7ad 320
252b5132
RH
321 for (opindex_ptr = op->operands, opnum = 1;
322 *opindex_ptr != 0;
323 opindex_ptr++, opnum++)
324 {
7d063384 325 bfd_boolean square = FALSE;
b34976b6
AM
326 long value;
327 int flag;
1cd986c5 328 char *prefix;
47b0e7ad 329
252b5132 330 operand = &v850_operands[*opindex_ptr];
47b0e7ad 331
78c8d46c
NC
332 value = get_operand_value (operand, insn, bytes_read, memaddr,
333 info, 0, 0);
252b5132
RH
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
47b0e7ad 351 in an instruction is the register for a memory address.
252b5132 352
04ee5257 353 The exception (and there's always an exception) are the
252b5132 354 "jmp" insn which needs square brackets around it's only
04ee5257
NC
355 register argument, and the clr1/not1/set1/tst1 insns
356 which [...] around their second register argument. */
357
1cd986c5
NC
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 }
252b5132 367
1cd986c5 368 if (opnum == 1 && opnum == memop)
7d063384
NC
369 {
370 info->fprintf_func (info->stream, "%s[", prefix);
371 square = TRUE;
372 }
78c8d46c
NC
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 }
1cd986c5 388 else if (opnum > 1
78c8d46c
NC
389 && (v850_operands[*(opindex_ptr - 1)].flags
390 & V850_OPERAND_DISP) != 0
1cd986c5 391 && opnum == memop)
7d063384
NC
392 {
393 info->fprintf_func (info->stream, "%s[", prefix);
394 square = TRUE;
395 }
04ee5257
NC
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 }
1cd986c5
NC
406 else if (opnum > 1)
407 info->fprintf_func (info->stream, ", %s", prefix);
408
78c8d46c
NC
409 /* Extract the flags, ignoring ones which do not
410 effect disassembly output. */
1cd986c5
NC
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
78c8d46c
NC
417 | V850_OPERAND_VREG
418 | V850_OPERAND_CACHEOP
419 | V850_OPERAND_PREFOP
1cd986c5 420 | V850_OPERAND_FLOAT_CC);
47b0e7ad 421
252b5132
RH
422 switch (flag)
423 {
78c8d46c
NC
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;
1cd986c5 436 case V850E_OPERAND_REG_LIST:
252b5132 437 {
1cd986c5
NC
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 };
b34976b6
AM
440 int *regs;
441 int i;
252b5132 442 unsigned long int mask = 0;
b34976b6 443 int pc = 0;
1cd986c5 444
252b5132
RH
445 switch (operand->shift)
446 {
447 case 0xffe00001: regs = list12_regs; break;
252b5132
RH
448 default:
449 /* xgettext:c-format */
78c8d46c 450 fprintf (stderr, _("unknown operand shift: %x\n"), operand->shift);
47b0e7ad 451 abort ();
252b5132
RH
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 */
1cd986c5 462 case 0: fprintf (stderr, _("unknown reg: %d\n"), i ); abort ();
b34976b6 463 case -1: pc = 1; break;
252b5132
RH
464 }
465 }
466 }
467
468 info->fprintf_func (info->stream, "{");
47b0e7ad 469
1cd986c5 470 if (mask || pc)
252b5132
RH
471 {
472 if (mask)
473 {
474 unsigned int bit;
b34976b6 475 int shown_one = 0;
47b0e7ad 476
252b5132
RH
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
b34976b6 486 shown_one = 1;
47b0e7ad 487
48891606 488 info->fprintf_func (info->stream, "%s", v850_reg_names[first]);
47b0e7ad 489
252b5132
RH
490 for (bit++; bit < 32; bit++)
491 if ((mask & (1 << bit)) == 0)
492 break;
493
494 last = bit;
495
496 if (last > first + 1)
1cd986c5
NC
497 {
498 info->fprintf_func (info->stream, " - %s", v850_reg_names[ last - 1 ]);
499 }
252b5132
RH
500 }
501 }
47b0e7ad 502
252b5132
RH
503 if (pc)
504 info->fprintf_func (info->stream, "%sPC", mask ? ", " : "");
252b5132 505 }
47b0e7ad 506
252b5132
RH
507 info->fprintf_func (info->stream, "}");
508 }
252b5132 509 break;
47b0e7ad 510
78c8d46c
NC
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;
1cd986c5
NC
558
559 default:
560 print_value (operand->flags, memaddr, info, value);
252b5132 561 break;
47b0e7ad 562 }
252b5132 563
7d063384 564 if (square)
252b5132
RH
565 (*info->fprintf_func) (info->stream, "]");
566 }
567
252b5132
RH
568 /* All done. */
569 break;
570 }
1cd986c5 571 next_opcode:
252b5132
RH
572 op++;
573 }
574
1cd986c5 575 return match;
252b5132
RH
576}
577
47b0e7ad
NC
578int
579print_insn_v850 (bfd_vma memaddr, struct disassemble_info * info)
252b5132 580{
1cd986c5
NC
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;
78c8d46c
NC
609
610 case bfd_mach_v850e3v5:
611 target_processor = PROCESSOR_V850E3V5;
612 break;
1cd986c5 613 }
252b5132 614
252b5132 615 status = info->read_memory_func (memaddr, buffer, 2, info);
1cd986c5
NC
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)
252b5132 628 {
1cd986c5
NC
629 insn2 = bfd_getl16 (buffer);
630 /* fprintf (stderr, "insn2 0x%08lx\n", insn2); */
631 }
47b0e7ad 632
1cd986c5
NC
633 /* Special case. */
634 if (length == 0
78c8d46c 635 && ((target_processor & PROCESSOR_V850E2_UP) != 0))
1cd986c5
NC
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)
252b5132 651 {
1cd986c5
NC
652 length = 2;
653 code_length = 6;
654 }
655 }
252b5132 656
1cd986c5 657 if (length == 0
78c8d46c
NC
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))
1cd986c5
NC
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;
252b5132
RH
696 }
697 }
47b0e7ad 698
1cd986c5
NC
699 if (length == 0
700 && target_processor != PROCESSOR_V850)
252b5132 701 {
1cd986c5
NC
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
78c8d46c
NC
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
1cd986c5
NC
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 }
252b5132
RH
782 }
783
1cd986c5 784 return code_length;
252b5132 785}
This page took 0.642936 seconds and 4 git commands to generate.