Fix a bug displaying the interpretation of a CFA block that just contains DW_CFA_NOP...
[deliverable/binutils-gdb.git] / opcodes / arc-dis.c
CommitLineData
252b5132 1/* Instruction printing code for the ARC.
6f2750fe 2 Copyright (C) 1994-2016 Free Software Foundation, Inc.
886a2506
NC
3
4 Contributed by Claudiu Zissulescu (claziss@synopsys.com)
252b5132 5
9b201bb5
NC
6 This file is part of libopcodes.
7
8 This library is free software; you can redistribute it and/or modify
0d2bcfaf 9 it under the terms of the GNU General Public License as published by
9b201bb5
NC
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
252b5132 12
9b201bb5
NC
13 It is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 License for more details.
252b5132 17
0d2bcfaf
NC
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
47b0e7ad
NC
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
252b5132 22
5eb3690e 23#include "sysdep.h"
886a2506
NC
24#include <stdio.h>
25#include <assert.h>
252b5132
RH
26#include "dis-asm.h"
27#include "opcode/arc.h"
0d2bcfaf
NC
28#include "arc-dis.h"
29#include "arc-ext.h"
252b5132 30
252b5132 31
886a2506 32/* Globals variables. */
82b829a7 33
886a2506 34static const char * const regnames[64] =
47b0e7ad 35{
886a2506
NC
36 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
37 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
38 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
39 "r24", "r25", "gp", "fp", "sp", "ilink", "r30", "blink",
40
41 "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
42 "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
43 "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",
44 "r56", "r57", "ACCL", "ACCH", "lp_count", "rezerved", "LIMM", "pcl"
45};
46
47/* Macros section. */
48
49#ifdef DEBUG
50# define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args)
51#else
52# define pr_debug(fmt, args...)
53#endif
54
55#define ARRANGE_ENDIAN(info, buf) \
56 (info->endian == BFD_ENDIAN_LITTLE ? bfd_getm32 (bfd_getl32 (buf)) \
57 : bfd_getb32 (buf))
58
59#define BITS(word,s,e) (((word) << (sizeof (word) * 8 - 1 - e)) >> \
60 (s + (sizeof (word) * 8 - 1 - e)))
279a96ca 61#define OPCODE(word) (BITS ((word), 27, 31))
252b5132 62
886a2506 63#define OPCODE_AC(word) (BITS ((word), 11, 15))
252b5132 64
886a2506 65/* Functions implementation. */
252b5132 66
886a2506
NC
67static bfd_vma
68bfd_getm32 (unsigned int data)
0d2bcfaf 69{
886a2506 70 bfd_vma value = 0;
0d2bcfaf 71
886a2506
NC
72 value = ((data & 0xff00) | (data & 0xff)) << 16;
73 value |= ((data & 0xff0000) | (data & 0xff000000)) >> 16;
74 return value;
0d2bcfaf
NC
75}
76
886a2506
NC
77static int
78special_flag_p (const char *opname,
79 const char *flgname)
0d2bcfaf 80{
886a2506 81 const struct arc_flag_special *flg_spec;
886a2506 82 unsigned i, j, flgidx;
0d2bcfaf 83
886a2506 84 for (i = 0; i < arc_num_flag_special; i++)
252b5132 85 {
886a2506 86 flg_spec = &arc_flag_special_cases[i];
279a96ca 87
24b368f8 88 if (strcmp (opname, flg_spec->name))
886a2506 89 continue;
279a96ca 90
886a2506
NC
91 /* Found potential special case instruction. */
92 for (j=0;; ++j)
0d2bcfaf 93 {
886a2506
NC
94 flgidx = flg_spec->flags[j];
95 if (flgidx == 0)
96 break; /* End of the array. */
0d2bcfaf 97
886a2506
NC
98 if (strcmp (flgname, arc_flag_operands[flgidx].name) == 0)
99 return 1;
252b5132 100 }
0d2bcfaf 101 }
886a2506 102 return 0;
0d2bcfaf 103}
252b5132 104
b99747ae
CZ
105/* Find proper format for the given opcode. */
106static const struct arc_opcode *
107find_format (const struct arc_opcode *arc_table,
cb040366 108 unsigned *insn, unsigned int insnLen,
b99747ae
CZ
109 unsigned isa_mask)
110{
111 unsigned int i = 0;
112 const struct arc_opcode *opcode = NULL;
113 const unsigned char *opidx;
114 const unsigned char *flgidx;
115
116 do {
117 bfd_boolean invalid = FALSE;
118
119 opcode = &arc_table[i++];
120
121 if (ARC_SHORT (opcode->mask) && (insnLen == 2))
122 {
123 if (OPCODE_AC (opcode->opcode) != OPCODE_AC (insn[0]))
124 continue;
125 }
126 else if (!ARC_SHORT (opcode->mask) && (insnLen == 4))
127 {
128 if (OPCODE (opcode->opcode) != OPCODE (insn[0]))
129 continue;
130 }
131 else
132 continue;
133
134 if ((insn[0] ^ opcode->opcode) & opcode->mask)
135 continue;
136
137 if (!(opcode->cpu & isa_mask))
138 continue;
139
140 /* Possible candidate, check the operands. */
141 for (opidx = opcode->operands; *opidx; opidx++)
142 {
143 int value;
144 const struct arc_operand *operand = &arc_operands[*opidx];
145
146 if (operand->flags & ARC_OPERAND_FAKE)
147 continue;
148
149 if (operand->extract)
150 value = (*operand->extract) (insn[0], &invalid);
151 else
152 value = (insn[0] >> operand->shift) & ((1 << operand->bits) - 1);
153
154 /* Check for LIMM indicator. If it is there, then make sure
155 we pick the right format. */
156 if (operand->flags & ARC_OPERAND_IR
157 && !(operand->flags & ARC_OPERAND_LIMM))
158 {
159 if ((value == 0x3E && insnLen == 4)
160 || (value == 0x1E && insnLen == 2))
161 {
162 invalid = TRUE;
163 break;
164 }
165 }
166 }
167
168 /* Check the flags. */
169 for (flgidx = opcode->flags; *flgidx; flgidx++)
170 {
171 /* Get a valid flag class. */
172 const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
173 const unsigned *flgopridx;
174 int foundA = 0, foundB = 0;
f36e33da 175 unsigned int value;
b99747ae 176
f36e33da 177 /* Check first the extensions. */
c810e0b8 178 if (cl_flags->flag_class & F_CLASS_EXTEND)
f36e33da
CZ
179 {
180 value = (insn[0] & 0x1F);
181 if (arcExtMap_condCodeName (value))
182 continue;
183 }
b99747ae
CZ
184 for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
185 {
186 const struct arc_flag_operand *flg_operand =
187 &arc_flag_operands[*flgopridx];
b99747ae
CZ
188
189 value = (insn[0] >> flg_operand->shift)
190 & ((1 << flg_operand->bits) - 1);
191 if (value == flg_operand->code)
192 foundA = 1;
193 if (value)
194 foundB = 1;
195 }
196 if (!foundA && foundB)
197 {
198 invalid = TRUE;
199 break;
200 }
201 }
202
203 if (invalid)
204 continue;
205
206 /* The instruction is valid. */
207 return opcode;
208 } while (opcode->mask);
209
210 return NULL;
211}
212
f36e33da
CZ
213static void
214print_flags (const struct arc_opcode *opcode,
215 unsigned *insn,
216 struct disassemble_info *info)
217{
218 const unsigned char *flgidx;
219 unsigned int value;
220
221 /* Now extract and print the flags. */
222 for (flgidx = opcode->flags; *flgidx; flgidx++)
223 {
224 /* Get a valid flag class. */
225 const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
226 const unsigned *flgopridx;
227
228 /* Check first the extensions. */
c810e0b8 229 if (cl_flags->flag_class & F_CLASS_EXTEND)
f36e33da
CZ
230 {
231 const char *name;
232 value = (insn[0] & 0x1F);
233
234 name = arcExtMap_condCodeName (value);
235 if (name)
236 {
237 (*info->fprintf_func) (info->stream, ".%s", name);
238 continue;
239 }
240 }
241
242 for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
243 {
244 const struct arc_flag_operand *flg_operand =
245 &arc_flag_operands[*flgopridx];
246
247 if (!flg_operand->favail)
248 continue;
249
250 value = (insn[0] >> flg_operand->shift)
251 & ((1 << flg_operand->bits) - 1);
252 if (value == flg_operand->code)
253 {
254 /* FIXME!: print correctly nt/t flag. */
255 if (!special_flag_p (opcode->name, flg_operand->name))
256 (*info->fprintf_func) (info->stream, ".");
257 else if (info->insn_type == dis_dref)
258 {
259 switch (flg_operand->name[0])
260 {
261 case 'b':
262 info->data_size = 1;
263 break;
264 case 'h':
265 case 'w':
266 info->data_size = 2;
267 break;
268 default:
269 info->data_size = 4;
270 break;
271 }
272 }
d9eca1df
CZ
273 if (flg_operand->name[0] == 'd'
274 && flg_operand->name[1] == 0)
275 info->branch_delay_insns = 1;
276
277 /* Check if it is a conditional flag. */
278 if (cl_flags->flag_class & F_CLASS_COND)
279 {
280 if (info->insn_type == dis_jsr)
281 info->insn_type = dis_condjsr;
282 else if (info->insn_type == dis_branch)
283 info->insn_type = dis_condbranch;
284 }
285
f36e33da
CZ
286 (*info->fprintf_func) (info->stream, "%s", flg_operand->name);
287 }
f36e33da
CZ
288 }
289 }
290}
291
292static const char *
293get_auxreg (const struct arc_opcode *opcode,
294 int value,
295 unsigned isa_mask)
296{
297 const char *name;
298 unsigned int i;
299 const struct arc_aux_reg *auxr = &arc_aux_regs[0];
300
c810e0b8 301 if (opcode->insn_class != AUXREG)
f36e33da
CZ
302 return NULL;
303
304 name = arcExtMap_auxRegName (value);
305 if (name)
306 return name;
307
308 for (i = 0; i < arc_num_aux_regs; i++, auxr++)
309 {
310 if (!(auxr->cpu & isa_mask))
311 continue;
312
313 if (auxr->subclass != NONE)
314 return NULL;
315
316 if (auxr->address == value)
317 return auxr->name;
318 }
319 return NULL;
320}
cb040366
AB
321
322/* Calculate the instruction length for an instruction starting with MSB
323 and LSB, the most and least significant byte. The ISA_MASK is used to
324 filter the instructions considered to only those that are part of the
325 current architecture.
326
327 The instruction lengths are calculated from the ARC_OPCODE table, and
328 cached for later use. */
329
330static unsigned int
331arc_insn_length (bfd_byte msb, struct disassemble_info *info)
332{
333 bfd_byte major_opcode = msb >> 3;
334
335 switch (info->mach)
336 {
337 case bfd_mach_arc_nps400:
338 case bfd_mach_arc_arc700:
339 case bfd_mach_arc_arc600:
340 return (major_opcode > 0xb) ? 2 : 4;
341 break;
342
343 case bfd_mach_arc_arcv2:
344 return (major_opcode > 0x7) ? 2 : 4;
345 break;
346
347 default:
348 abort ();
349 }
350}
351
886a2506 352/* Disassemble ARC instructions. */
0d2bcfaf 353
886a2506
NC
354static int
355print_insn_arc (bfd_vma memaddr,
356 struct disassemble_info *info)
0d2bcfaf 357{
886a2506
NC
358 bfd_byte buffer[4];
359 unsigned int lowbyte, highbyte;
360 int status;
cb040366 361 unsigned int insnLen;
3f94e60d
NC
362 unsigned insn[2] = { 0, 0 };
363 unsigned isa_mask;
886a2506 364 const unsigned char *opidx;
886a2506 365 const struct arc_opcode *opcode;
b99747ae 366 const extInstruction_t *einsn;
886a2506
NC
367 bfd_boolean need_comma;
368 bfd_boolean open_braket;
24b368f8 369 int size;
0d2bcfaf 370
886a2506
NC
371 lowbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 1 : 0);
372 highbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 0 : 1);
0d2bcfaf 373
886a2506
NC
374 switch (info->mach)
375 {
8699fc3e
AB
376 case bfd_mach_arc_nps400:
377 isa_mask = ARC_OPCODE_ARC700 | ARC_OPCODE_NPS400;
378 break;
379
886a2506
NC
380 case bfd_mach_arc_arc700:
381 isa_mask = ARC_OPCODE_ARC700;
382 break;
0d2bcfaf 383
886a2506
NC
384 case bfd_mach_arc_arc600:
385 isa_mask = ARC_OPCODE_ARC600;
386 break;
0d2bcfaf 387
886a2506
NC
388 case bfd_mach_arc_arcv2:
389 default:
390 isa_mask = ARC_OPCODE_ARCv2HS | ARC_OPCODE_ARCv2EM;
391 break;
0d2bcfaf
NC
392 }
393
24b368f8
CZ
394 /* This variable may be set by the instruction decoder. It suggests
395 the number of bytes objdump should display on a single line. If
396 the instruction decoder sets this, it should always set it to
397 the same value in order to get reasonable looking output. */
398
399 info->bytes_per_line = 8;
400
401 /* In the next lines, we set two info variables control the way
402 objdump displays the raw data. For example, if bytes_per_line is
403 8 and bytes_per_chunk is 4, the output will look like this:
404 00: 00000000 00000000
405 with the chunks displayed according to "display_endian". */
406
407 if (info->section
408 && !(info->section->flags & SEC_CODE))
409 {
410 /* This is not a CODE section. */
411 switch (info->section->size)
412 {
413 case 1:
414 case 2:
415 case 4:
416 size = info->section->size;
417 break;
418 default:
419 size = (info->section->size & 0x01) ? 1 : 4;
420 break;
421 }
422 info->bytes_per_chunk = 1;
423 info->display_endian = info->endian;
424 }
425 else
426 {
427 size = 2;
428 info->bytes_per_chunk = 2;
429 info->display_endian = info->endian;
430 }
431
886a2506 432 /* Read the insn into a host word. */
24b368f8 433 status = (*info->read_memory_func) (memaddr, buffer, size, info);
886a2506 434 if (status != 0)
0d2bcfaf 435 {
886a2506
NC
436 (*info->memory_error_func) (status, memaddr, info);
437 return -1;
0d2bcfaf
NC
438 }
439
886a2506
NC
440 if (info->section
441 && !(info->section->flags & SEC_CODE))
0d2bcfaf 442 {
24b368f8
CZ
443 /* Data section. */
444 unsigned long data;
445
446 data = bfd_get_bits (buffer, size * 8,
447 info->display_endian == BFD_ENDIAN_BIG);
448 switch (size)
0d2bcfaf 449 {
24b368f8
CZ
450 case 1:
451 (*info->fprintf_func) (info->stream, ".byte\t0x%02lx", data);
452 break;
453 case 2:
454 (*info->fprintf_func) (info->stream, ".short\t0x%04lx", data);
455 break;
456 case 4:
457 (*info->fprintf_func) (info->stream, ".word\t0x%08lx", data);
458 break;
459 default:
460 abort ();
0d2bcfaf 461 }
24b368f8 462 return size;
886a2506 463 }
279a96ca 464
cb040366
AB
465 insnLen = arc_insn_length (buffer[lowbyte], info);
466 switch (insnLen)
886a2506 467 {
cb040366 468 case 2:
886a2506 469 insn[0] = (buffer[lowbyte] << 8) | buffer[highbyte];
cb040366 470 break;
886a2506 471
cb040366
AB
472 default:
473 /* An unknown instruction is treated as being length 4. This is
474 possibly not the best solution, but matches the behaviour that was
475 in place before the table based instruction length look-up was
476 introduced. */
477 case 4:
886a2506
NC
478 /* This is a long instruction: Read the remaning 2 bytes. */
479 status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 2, info);
480 if (status != 0)
0d2bcfaf 481 {
886a2506
NC
482 (*info->memory_error_func) (status, memaddr + 2, info);
483 return -1;
0d2bcfaf 484 }
886a2506 485 insn[0] = ARRANGE_ENDIAN (info, buffer);
cb040366 486 break;
886a2506
NC
487 }
488
886a2506
NC
489 /* Set some defaults for the insn info. */
490 info->insn_info_valid = 1;
491 info->branch_delay_insns = 0;
492 info->data_size = 0;
493 info->insn_type = dis_nonbranch;
494 info->target = 0;
495 info->target2 = 0;
496
497 /* FIXME to be moved in dissasemble_init_for_target. */
498 info->disassembler_needs_relocs = TRUE;
499
500 /* Find the first match in the opcode table. */
b99747ae 501 opcode = find_format (arc_opcodes, insn, insnLen, isa_mask);
886a2506 502
b99747ae
CZ
503 if (!opcode)
504 {
505 /* No instruction found. Try the extensions. */
506 einsn = arcExtMap_insn (OPCODE (insn[0]), insn[0]);
507 if (einsn)
0d2bcfaf 508 {
b99747ae
CZ
509 const char *errmsg = NULL;
510 opcode = arcExtMap_genOpcode (einsn, isa_mask, &errmsg);
511 if (opcode == NULL)
252b5132 512 {
b99747ae
CZ
513 (*info->fprintf_func) (info->stream,
514 "An error occured while "
515 "generating the extension instruction "
516 "operations");
517 return -1;
252b5132 518 }
252b5132 519
b99747ae
CZ
520 opcode = find_format (opcode, insn, insnLen, isa_mask);
521 assert (opcode != NULL);
522 }
523 else
0d2bcfaf 524 {
b99747ae
CZ
525 if (insnLen == 2)
526 (*info->fprintf_func) (info->stream, ".long %#04x", insn[0]);
527 else
528 (*info->fprintf_func) (info->stream, ".long %#08x", insn[0]);
886a2506 529
b99747ae
CZ
530 info->insn_type = dis_noninsn;
531 return insnLen;
0d2bcfaf 532 }
886a2506 533 }
279a96ca 534
886a2506
NC
535 /* Print the mnemonic. */
536 (*info->fprintf_func) (info->stream, "%s", opcode->name);
537
538 /* Preselect the insn class. */
c810e0b8 539 switch (opcode->insn_class)
886a2506
NC
540 {
541 case BRANCH:
542 case JUMP:
543 if (!strncmp (opcode->name, "bl", 2)
544 || !strncmp (opcode->name, "jl", 2))
d9eca1df
CZ
545 {
546 if (opcode->subclass == COND)
547 info->insn_type = dis_condjsr;
548 else
549 info->insn_type = dis_jsr;
550 }
279a96ca 551 else
d9eca1df
CZ
552 {
553 if (opcode->subclass == COND)
554 info->insn_type = dis_condbranch;
555 else
556 info->insn_type = dis_branch;
557 }
886a2506
NC
558 break;
559 case MEMORY:
560 info->insn_type = dis_dref; /* FIXME! DB indicates mov as memory! */
0d2bcfaf 561 break;
0d2bcfaf 562 default:
886a2506 563 info->insn_type = dis_nonbranch;
0d2bcfaf
NC
564 break;
565 }
279a96ca 566
886a2506 567 pr_debug ("%s: 0x%08x\n", opcode->name, opcode->opcode);
279a96ca 568
f36e33da 569 print_flags (opcode, insn, info);
279a96ca 570
886a2506
NC
571 if (opcode->operands[0] != 0)
572 (*info->fprintf_func) (info->stream, "\t");
279a96ca 573
886a2506
NC
574 need_comma = FALSE;
575 open_braket = FALSE;
279a96ca 576
886a2506
NC
577 /* Now extract and print the operands. */
578 for (opidx = opcode->operands; *opidx; opidx++)
579 {
580 const struct arc_operand *operand = &arc_operands[*opidx];
581 int value;
279a96ca 582
886a2506 583 if (open_braket && (operand->flags & ARC_OPERAND_BRAKET))
0d2bcfaf 584 {
886a2506
NC
585 (*info->fprintf_func) (info->stream, "]");
586 open_braket = FALSE;
587 continue;
0d2bcfaf 588 }
279a96ca 589
886a2506
NC
590 /* Only take input from real operands. */
591 if ((operand->flags & ARC_OPERAND_FAKE)
592 && !(operand->flags & ARC_OPERAND_BRAKET))
593 continue;
279a96ca 594
886a2506
NC
595 if (operand->extract)
596 value = (*operand->extract) (insn[0], (int *) NULL);
0d2bcfaf 597 else
0d2bcfaf 598 {
886a2506 599 if (operand->flags & ARC_OPERAND_ALIGNED32)
0d2bcfaf 600 {
886a2506
NC
601 value = (insn[0] >> operand->shift)
602 & ((1 << (operand->bits - 2)) - 1);
603 value = value << 2;
252b5132 604 }
252b5132 605 else
886a2506
NC
606 {
607 value = (insn[0] >> operand->shift) & ((1 << operand->bits) - 1);
608 }
609 if (operand->flags & ARC_OPERAND_SIGNED)
610 {
611 int signbit = 1 << (operand->bits - 1);
612 value = (value ^ signbit) - signbit;
613 }
252b5132 614 }
279a96ca 615
886a2506
NC
616 if (operand->flags & ARC_OPERAND_IGNORE
617 && (operand->flags & ARC_OPERAND_IR
618 && value == -1))
619 continue;
279a96ca 620
886a2506
NC
621 if (need_comma)
622 (*info->fprintf_func) (info->stream, ",");
279a96ca 623
886a2506 624 if (!open_braket && (operand->flags & ARC_OPERAND_BRAKET))
0d2bcfaf 625 {
886a2506
NC
626 (*info->fprintf_func) (info->stream, "[");
627 open_braket = TRUE;
628 need_comma = FALSE;
629 continue;
0d2bcfaf 630 }
886a2506
NC
631
632 /* Read the limm operand, if required. */
633 if (operand->flags & ARC_OPERAND_LIMM
634 && !(operand->flags & ARC_OPERAND_DUPLICATE))
0d2bcfaf 635 {
886a2506
NC
636 status = (*info->read_memory_func) (memaddr + insnLen, buffer,
637 4, info);
638 if (status != 0)
0d2bcfaf 639 {
886a2506
NC
640 (*info->memory_error_func) (status, memaddr + insnLen, info);
641 return -1;
0d2bcfaf 642 }
886a2506 643 insn[1] = ARRANGE_ENDIAN (info, buffer);
0d2bcfaf 644 }
279a96ca 645
886a2506
NC
646 /* Print the operand as directed by the flags. */
647 if (operand->flags & ARC_OPERAND_IR)
648 {
f36e33da
CZ
649 const char *rname;
650
886a2506 651 assert (value >=0 && value < 64);
f36e33da
CZ
652 rname = arcExtMap_coreRegName (value);
653 if (!rname)
654 rname = regnames[value];
655 (*info->fprintf_func) (info->stream, "%s", rname);
886a2506 656 if (operand->flags & ARC_OPERAND_TRUNCATE)
f36e33da
CZ
657 {
658 rname = arcExtMap_coreRegName (value + 1);
659 if (!rname)
660 rname = regnames[value + 1];
661 (*info->fprintf_func) (info->stream, "%s", rname);
662 }
886a2506
NC
663 }
664 else if (operand->flags & ARC_OPERAND_LIMM)
665 {
f36e33da
CZ
666 const char *rname = get_auxreg (opcode, insn[1], isa_mask);
667 if (rname && open_braket)
668 (*info->fprintf_func) (info->stream, "%s", rname);
669 else
670 {
671 (*info->fprintf_func) (info->stream, "%#x", insn[1]);
672 if (info->insn_type == dis_branch
673 || info->insn_type == dis_jsr)
674 info->target = (bfd_vma) insn[1];
675 }
886a2506
NC
676 }
677 else if (operand->flags & ARC_OPERAND_PCREL)
678 {
679 /* PCL relative. */
680 if (info->flags & INSN_HAS_RELOC)
681 memaddr = 0;
682 (*info->print_address_func) ((memaddr & ~3) + value, info);
279a96ca 683
886a2506
NC
684 info->target = (bfd_vma) (memaddr & ~3) + value;
685 }
686 else if (operand->flags & ARC_OPERAND_SIGNED)
f36e33da
CZ
687 {
688 const char *rname = get_auxreg (opcode, value, isa_mask);
689 if (rname && open_braket)
690 (*info->fprintf_func) (info->stream, "%s", rname);
691 else
692 (*info->fprintf_func) (info->stream, "%d", value);
693 }
886a2506 694 else
f36e33da
CZ
695 {
696 if (operand->flags & ARC_OPERAND_TRUNCATE
697 && !(operand->flags & ARC_OPERAND_ALIGNED32)
698 && !(operand->flags & ARC_OPERAND_ALIGNED16)
699 && value > 0 && value <= 14)
700 (*info->fprintf_func) (info->stream, "r13-%s",
701 regnames[13 + value - 1]);
702 else
703 {
704 const char *rname = get_auxreg (opcode, value, isa_mask);
705 if (rname && open_braket)
706 (*info->fprintf_func) (info->stream, "%s", rname);
707 else
708 (*info->fprintf_func) (info->stream, "%#x", value);
709 }
710 }
886a2506
NC
711
712 need_comma = TRUE;
713
714 /* Adjust insn len. */
715 if (operand->flags & ARC_OPERAND_LIMM
716 && !(operand->flags & ARC_OPERAND_DUPLICATE))
717 insnLen += 4;
252b5132 718 }
279a96ca 719
886a2506 720 return insnLen;
252b5132
RH
721}
722
47b0e7ad 723
886a2506
NC
724disassembler_ftype
725arc_get_disassembler (bfd *abfd)
252b5132 726{
886a2506
NC
727 /* Read the extenssion insns and registers, if any. */
728 build_ARC_extmap (abfd);
b99747ae 729#ifdef DEBUG
886a2506 730 dump_ARC_extmap ();
b99747ae 731#endif
252b5132 732
886a2506 733 return print_insn_arc;
252b5132
RH
734}
735
886a2506 736/* Disassemble ARC instructions. Used by debugger. */
47b0e7ad 737
886a2506
NC
738struct arcDisState
739arcAnalyzeInstr (bfd_vma memaddr,
740 struct disassemble_info *info)
0d2bcfaf 741{
886a2506
NC
742 struct arcDisState ret;
743 memset (&ret, 0, sizeof (struct arcDisState));
744
745 ret.instructionLen = print_insn_arc (memaddr, info);
746
747#if 0
748 ret.words[0] = insn[0];
749 ret.words[1] = insn[1];
750 ret._this = &ret;
751 ret.coreRegName = _coreRegName;
752 ret.auxRegName = _auxRegName;
753 ret.condCodeName = _condCodeName;
754 ret.instName = _instName;
755#endif
47b0e7ad 756
886a2506 757 return ret;
0d2bcfaf
NC
758}
759
886a2506
NC
760/* Local variables:
761 eval: (c-set-style "gnu")
762 indent-tabs-mode: t
763 End: */
This page took 0.986902 seconds and 4 git commands to generate.