[ARC] Add XY registers, update neg instruction.
[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 }
273 (*info->fprintf_func) (info->stream, "%s", flg_operand->name);
274 }
275
276 if (flg_operand->name[0] == 'd'
277 && flg_operand->name[1] == 0)
278 info->branch_delay_insns = 1;
279 }
280 }
281}
282
283static const char *
284get_auxreg (const struct arc_opcode *opcode,
285 int value,
286 unsigned isa_mask)
287{
288 const char *name;
289 unsigned int i;
290 const struct arc_aux_reg *auxr = &arc_aux_regs[0];
291
c810e0b8 292 if (opcode->insn_class != AUXREG)
f36e33da
CZ
293 return NULL;
294
295 name = arcExtMap_auxRegName (value);
296 if (name)
297 return name;
298
299 for (i = 0; i < arc_num_aux_regs; i++, auxr++)
300 {
301 if (!(auxr->cpu & isa_mask))
302 continue;
303
304 if (auxr->subclass != NONE)
305 return NULL;
306
307 if (auxr->address == value)
308 return auxr->name;
309 }
310 return NULL;
311}
cb040366
AB
312
313/* Calculate the instruction length for an instruction starting with MSB
314 and LSB, the most and least significant byte. The ISA_MASK is used to
315 filter the instructions considered to only those that are part of the
316 current architecture.
317
318 The instruction lengths are calculated from the ARC_OPCODE table, and
319 cached for later use. */
320
321static unsigned int
322arc_insn_length (bfd_byte msb, struct disassemble_info *info)
323{
324 bfd_byte major_opcode = msb >> 3;
325
326 switch (info->mach)
327 {
328 case bfd_mach_arc_nps400:
329 case bfd_mach_arc_arc700:
330 case bfd_mach_arc_arc600:
331 return (major_opcode > 0xb) ? 2 : 4;
332 break;
333
334 case bfd_mach_arc_arcv2:
335 return (major_opcode > 0x7) ? 2 : 4;
336 break;
337
338 default:
339 abort ();
340 }
341}
342
886a2506 343/* Disassemble ARC instructions. */
0d2bcfaf 344
886a2506
NC
345static int
346print_insn_arc (bfd_vma memaddr,
347 struct disassemble_info *info)
0d2bcfaf 348{
886a2506
NC
349 bfd_byte buffer[4];
350 unsigned int lowbyte, highbyte;
351 int status;
cb040366 352 unsigned int insnLen;
3f94e60d
NC
353 unsigned insn[2] = { 0, 0 };
354 unsigned isa_mask;
886a2506 355 const unsigned char *opidx;
886a2506 356 const struct arc_opcode *opcode;
b99747ae 357 const extInstruction_t *einsn;
886a2506
NC
358 bfd_boolean need_comma;
359 bfd_boolean open_braket;
24b368f8 360 int size;
0d2bcfaf 361
886a2506
NC
362 lowbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 1 : 0);
363 highbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 0 : 1);
0d2bcfaf 364
886a2506
NC
365 switch (info->mach)
366 {
8699fc3e
AB
367 case bfd_mach_arc_nps400:
368 isa_mask = ARC_OPCODE_ARC700 | ARC_OPCODE_NPS400;
369 break;
370
886a2506
NC
371 case bfd_mach_arc_arc700:
372 isa_mask = ARC_OPCODE_ARC700;
373 break;
0d2bcfaf 374
886a2506
NC
375 case bfd_mach_arc_arc600:
376 isa_mask = ARC_OPCODE_ARC600;
377 break;
0d2bcfaf 378
886a2506
NC
379 case bfd_mach_arc_arcv2:
380 default:
381 isa_mask = ARC_OPCODE_ARCv2HS | ARC_OPCODE_ARCv2EM;
382 break;
0d2bcfaf
NC
383 }
384
24b368f8
CZ
385 /* This variable may be set by the instruction decoder. It suggests
386 the number of bytes objdump should display on a single line. If
387 the instruction decoder sets this, it should always set it to
388 the same value in order to get reasonable looking output. */
389
390 info->bytes_per_line = 8;
391
392 /* In the next lines, we set two info variables control the way
393 objdump displays the raw data. For example, if bytes_per_line is
394 8 and bytes_per_chunk is 4, the output will look like this:
395 00: 00000000 00000000
396 with the chunks displayed according to "display_endian". */
397
398 if (info->section
399 && !(info->section->flags & SEC_CODE))
400 {
401 /* This is not a CODE section. */
402 switch (info->section->size)
403 {
404 case 1:
405 case 2:
406 case 4:
407 size = info->section->size;
408 break;
409 default:
410 size = (info->section->size & 0x01) ? 1 : 4;
411 break;
412 }
413 info->bytes_per_chunk = 1;
414 info->display_endian = info->endian;
415 }
416 else
417 {
418 size = 2;
419 info->bytes_per_chunk = 2;
420 info->display_endian = info->endian;
421 }
422
886a2506 423 /* Read the insn into a host word. */
24b368f8 424 status = (*info->read_memory_func) (memaddr, buffer, size, info);
886a2506 425 if (status != 0)
0d2bcfaf 426 {
886a2506
NC
427 (*info->memory_error_func) (status, memaddr, info);
428 return -1;
0d2bcfaf
NC
429 }
430
886a2506
NC
431 if (info->section
432 && !(info->section->flags & SEC_CODE))
0d2bcfaf 433 {
24b368f8
CZ
434 /* Data section. */
435 unsigned long data;
436
437 data = bfd_get_bits (buffer, size * 8,
438 info->display_endian == BFD_ENDIAN_BIG);
439 switch (size)
0d2bcfaf 440 {
24b368f8
CZ
441 case 1:
442 (*info->fprintf_func) (info->stream, ".byte\t0x%02lx", data);
443 break;
444 case 2:
445 (*info->fprintf_func) (info->stream, ".short\t0x%04lx", data);
446 break;
447 case 4:
448 (*info->fprintf_func) (info->stream, ".word\t0x%08lx", data);
449 break;
450 default:
451 abort ();
0d2bcfaf 452 }
24b368f8 453 return size;
886a2506 454 }
279a96ca 455
cb040366
AB
456 insnLen = arc_insn_length (buffer[lowbyte], info);
457 switch (insnLen)
886a2506 458 {
cb040366 459 case 2:
886a2506 460 insn[0] = (buffer[lowbyte] << 8) | buffer[highbyte];
cb040366 461 break;
886a2506 462
cb040366
AB
463 default:
464 /* An unknown instruction is treated as being length 4. This is
465 possibly not the best solution, but matches the behaviour that was
466 in place before the table based instruction length look-up was
467 introduced. */
468 case 4:
886a2506
NC
469 /* This is a long instruction: Read the remaning 2 bytes. */
470 status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 2, info);
471 if (status != 0)
0d2bcfaf 472 {
886a2506
NC
473 (*info->memory_error_func) (status, memaddr + 2, info);
474 return -1;
0d2bcfaf 475 }
886a2506 476 insn[0] = ARRANGE_ENDIAN (info, buffer);
cb040366 477 break;
886a2506
NC
478 }
479
886a2506
NC
480 /* Set some defaults for the insn info. */
481 info->insn_info_valid = 1;
482 info->branch_delay_insns = 0;
483 info->data_size = 0;
484 info->insn_type = dis_nonbranch;
485 info->target = 0;
486 info->target2 = 0;
487
488 /* FIXME to be moved in dissasemble_init_for_target. */
489 info->disassembler_needs_relocs = TRUE;
490
491 /* Find the first match in the opcode table. */
b99747ae 492 opcode = find_format (arc_opcodes, insn, insnLen, isa_mask);
886a2506 493
b99747ae
CZ
494 if (!opcode)
495 {
496 /* No instruction found. Try the extensions. */
497 einsn = arcExtMap_insn (OPCODE (insn[0]), insn[0]);
498 if (einsn)
0d2bcfaf 499 {
b99747ae
CZ
500 const char *errmsg = NULL;
501 opcode = arcExtMap_genOpcode (einsn, isa_mask, &errmsg);
502 if (opcode == NULL)
252b5132 503 {
b99747ae
CZ
504 (*info->fprintf_func) (info->stream,
505 "An error occured while "
506 "generating the extension instruction "
507 "operations");
508 return -1;
252b5132 509 }
252b5132 510
b99747ae
CZ
511 opcode = find_format (opcode, insn, insnLen, isa_mask);
512 assert (opcode != NULL);
513 }
514 else
0d2bcfaf 515 {
b99747ae
CZ
516 if (insnLen == 2)
517 (*info->fprintf_func) (info->stream, ".long %#04x", insn[0]);
518 else
519 (*info->fprintf_func) (info->stream, ".long %#08x", insn[0]);
886a2506 520
b99747ae
CZ
521 info->insn_type = dis_noninsn;
522 return insnLen;
0d2bcfaf 523 }
886a2506 524 }
279a96ca 525
886a2506
NC
526 /* Print the mnemonic. */
527 (*info->fprintf_func) (info->stream, "%s", opcode->name);
528
529 /* Preselect the insn class. */
c810e0b8 530 switch (opcode->insn_class)
886a2506
NC
531 {
532 case BRANCH:
533 case JUMP:
534 if (!strncmp (opcode->name, "bl", 2)
535 || !strncmp (opcode->name, "jl", 2))
536 info->insn_type = dis_jsr;
279a96ca 537 else
886a2506
NC
538 info->insn_type = dis_branch;
539 break;
540 case MEMORY:
541 info->insn_type = dis_dref; /* FIXME! DB indicates mov as memory! */
0d2bcfaf 542 break;
0d2bcfaf 543 default:
886a2506 544 info->insn_type = dis_nonbranch;
0d2bcfaf
NC
545 break;
546 }
279a96ca 547
886a2506 548 pr_debug ("%s: 0x%08x\n", opcode->name, opcode->opcode);
279a96ca 549
f36e33da 550 print_flags (opcode, insn, info);
279a96ca 551
886a2506
NC
552 if (opcode->operands[0] != 0)
553 (*info->fprintf_func) (info->stream, "\t");
279a96ca 554
886a2506
NC
555 need_comma = FALSE;
556 open_braket = FALSE;
279a96ca 557
886a2506
NC
558 /* Now extract and print the operands. */
559 for (opidx = opcode->operands; *opidx; opidx++)
560 {
561 const struct arc_operand *operand = &arc_operands[*opidx];
562 int value;
279a96ca 563
886a2506 564 if (open_braket && (operand->flags & ARC_OPERAND_BRAKET))
0d2bcfaf 565 {
886a2506
NC
566 (*info->fprintf_func) (info->stream, "]");
567 open_braket = FALSE;
568 continue;
0d2bcfaf 569 }
279a96ca 570
886a2506
NC
571 /* Only take input from real operands. */
572 if ((operand->flags & ARC_OPERAND_FAKE)
573 && !(operand->flags & ARC_OPERAND_BRAKET))
574 continue;
279a96ca 575
886a2506
NC
576 if (operand->extract)
577 value = (*operand->extract) (insn[0], (int *) NULL);
0d2bcfaf 578 else
0d2bcfaf 579 {
886a2506 580 if (operand->flags & ARC_OPERAND_ALIGNED32)
0d2bcfaf 581 {
886a2506
NC
582 value = (insn[0] >> operand->shift)
583 & ((1 << (operand->bits - 2)) - 1);
584 value = value << 2;
252b5132 585 }
252b5132 586 else
886a2506
NC
587 {
588 value = (insn[0] >> operand->shift) & ((1 << operand->bits) - 1);
589 }
590 if (operand->flags & ARC_OPERAND_SIGNED)
591 {
592 int signbit = 1 << (operand->bits - 1);
593 value = (value ^ signbit) - signbit;
594 }
252b5132 595 }
279a96ca 596
886a2506
NC
597 if (operand->flags & ARC_OPERAND_IGNORE
598 && (operand->flags & ARC_OPERAND_IR
599 && value == -1))
600 continue;
279a96ca 601
886a2506
NC
602 if (need_comma)
603 (*info->fprintf_func) (info->stream, ",");
279a96ca 604
886a2506 605 if (!open_braket && (operand->flags & ARC_OPERAND_BRAKET))
0d2bcfaf 606 {
886a2506
NC
607 (*info->fprintf_func) (info->stream, "[");
608 open_braket = TRUE;
609 need_comma = FALSE;
610 continue;
0d2bcfaf 611 }
886a2506
NC
612
613 /* Read the limm operand, if required. */
614 if (operand->flags & ARC_OPERAND_LIMM
615 && !(operand->flags & ARC_OPERAND_DUPLICATE))
0d2bcfaf 616 {
886a2506
NC
617 status = (*info->read_memory_func) (memaddr + insnLen, buffer,
618 4, info);
619 if (status != 0)
0d2bcfaf 620 {
886a2506
NC
621 (*info->memory_error_func) (status, memaddr + insnLen, info);
622 return -1;
0d2bcfaf 623 }
886a2506 624 insn[1] = ARRANGE_ENDIAN (info, buffer);
0d2bcfaf 625 }
279a96ca 626
886a2506
NC
627 /* Print the operand as directed by the flags. */
628 if (operand->flags & ARC_OPERAND_IR)
629 {
f36e33da
CZ
630 const char *rname;
631
886a2506 632 assert (value >=0 && value < 64);
f36e33da
CZ
633 rname = arcExtMap_coreRegName (value);
634 if (!rname)
635 rname = regnames[value];
636 (*info->fprintf_func) (info->stream, "%s", rname);
886a2506 637 if (operand->flags & ARC_OPERAND_TRUNCATE)
f36e33da
CZ
638 {
639 rname = arcExtMap_coreRegName (value + 1);
640 if (!rname)
641 rname = regnames[value + 1];
642 (*info->fprintf_func) (info->stream, "%s", rname);
643 }
886a2506
NC
644 }
645 else if (operand->flags & ARC_OPERAND_LIMM)
646 {
f36e33da
CZ
647 const char *rname = get_auxreg (opcode, insn[1], isa_mask);
648 if (rname && open_braket)
649 (*info->fprintf_func) (info->stream, "%s", rname);
650 else
651 {
652 (*info->fprintf_func) (info->stream, "%#x", insn[1]);
653 if (info->insn_type == dis_branch
654 || info->insn_type == dis_jsr)
655 info->target = (bfd_vma) insn[1];
656 }
886a2506
NC
657 }
658 else if (operand->flags & ARC_OPERAND_PCREL)
659 {
660 /* PCL relative. */
661 if (info->flags & INSN_HAS_RELOC)
662 memaddr = 0;
663 (*info->print_address_func) ((memaddr & ~3) + value, info);
279a96ca 664
886a2506
NC
665 info->target = (bfd_vma) (memaddr & ~3) + value;
666 }
667 else if (operand->flags & ARC_OPERAND_SIGNED)
f36e33da
CZ
668 {
669 const char *rname = get_auxreg (opcode, value, isa_mask);
670 if (rname && open_braket)
671 (*info->fprintf_func) (info->stream, "%s", rname);
672 else
673 (*info->fprintf_func) (info->stream, "%d", value);
674 }
886a2506 675 else
f36e33da
CZ
676 {
677 if (operand->flags & ARC_OPERAND_TRUNCATE
678 && !(operand->flags & ARC_OPERAND_ALIGNED32)
679 && !(operand->flags & ARC_OPERAND_ALIGNED16)
680 && value > 0 && value <= 14)
681 (*info->fprintf_func) (info->stream, "r13-%s",
682 regnames[13 + value - 1]);
683 else
684 {
685 const char *rname = get_auxreg (opcode, value, isa_mask);
686 if (rname && open_braket)
687 (*info->fprintf_func) (info->stream, "%s", rname);
688 else
689 (*info->fprintf_func) (info->stream, "%#x", value);
690 }
691 }
886a2506
NC
692
693 need_comma = TRUE;
694
695 /* Adjust insn len. */
696 if (operand->flags & ARC_OPERAND_LIMM
697 && !(operand->flags & ARC_OPERAND_DUPLICATE))
698 insnLen += 4;
252b5132 699 }
279a96ca 700
886a2506 701 return insnLen;
252b5132
RH
702}
703
47b0e7ad 704
886a2506
NC
705disassembler_ftype
706arc_get_disassembler (bfd *abfd)
252b5132 707{
886a2506
NC
708 /* Read the extenssion insns and registers, if any. */
709 build_ARC_extmap (abfd);
b99747ae 710#ifdef DEBUG
886a2506 711 dump_ARC_extmap ();
b99747ae 712#endif
252b5132 713
886a2506 714 return print_insn_arc;
252b5132
RH
715}
716
886a2506 717/* Disassemble ARC instructions. Used by debugger. */
47b0e7ad 718
886a2506
NC
719struct arcDisState
720arcAnalyzeInstr (bfd_vma memaddr,
721 struct disassemble_info *info)
0d2bcfaf 722{
886a2506
NC
723 struct arcDisState ret;
724 memset (&ret, 0, sizeof (struct arcDisState));
725
726 ret.instructionLen = print_insn_arc (memaddr, info);
727
728#if 0
729 ret.words[0] = insn[0];
730 ret.words[1] = insn[1];
731 ret._this = &ret;
732 ret.coreRegName = _coreRegName;
733 ret.auxRegName = _auxRegName;
734 ret.condCodeName = _condCodeName;
735 ret.instName = _instName;
736#endif
47b0e7ad 737
886a2506 738 return ret;
0d2bcfaf
NC
739}
740
886a2506
NC
741/* Local variables:
742 eval: (c-set-style "gnu")
743 indent-tabs-mode: t
744 End: */
This page took 0.887336 seconds and 4 git commands to generate.