1 /* Instruction printing code for the ARC.
2 Copyright (C) 1994-2016 Free Software Foundation, Inc.
6 This file is part of libopcodes.
8 This library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
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.
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
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
27 #include "opcode/arc.h"
32 #include "libiberty.h"
35 /* Structure used to iterate over, and extract the values for, operands of
38 struct arc_operand_iterator
40 /* The complete instruction value to extract operands from. */
41 unsigned long long insn;
43 /* The LIMM if this is being tracked separately. This field is only
44 valid if we find the LIMM operand in the operand list. */
47 /* The opcode this iterator is operating on. */
48 const struct arc_opcode *opcode;
50 /* The index into the opcodes operand index list. */
51 const unsigned char *opidx;
54 /* Globals variables. */
56 static const char * const regnames[64] =
58 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
59 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
60 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
61 "r24", "r25", "gp", "fp", "sp", "ilink", "r30", "blink",
63 "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
64 "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
65 "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",
66 "r56", "r57", "ACCL", "ACCH", "lp_count", "rezerved", "LIMM", "pcl"
69 static const char * const addrtypenames[ARC_NUM_ADDRTYPES] =
71 "bd", "jid", "lbd", "mbd", "sd", "sm", "xa", "xd",
72 "cd", "cbd", "cjid", "clbd", "cm", "csd", "cxa", "cxd"
75 static int addrtypenames_max = ARC_NUM_ADDRTYPES - 1;
77 static const char * const addrtypeunknown = "unknown";
79 /* This structure keeps track which instruction class(es)
80 should be ignored durring disassembling. */
82 typedef struct skipclass
84 insn_class_t insn_class;
85 insn_subclass_t subclass;
86 struct skipclass *nxt;
87 } skipclass_t, *linkclass;
89 /* Intial classes of instructions to be consider first when
91 static linkclass decodelist = NULL;
96 # define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args)
98 # define pr_debug(fmt, args...)
101 #define ARRANGE_ENDIAN(info, buf) \
102 (info->endian == BFD_ENDIAN_LITTLE ? bfd_getm32 (bfd_getl32 (buf)) \
105 #define BITS(word,s,e) (((word) << (sizeof (word) * 8 - 1 - e)) >> \
106 (s + (sizeof (word) * 8 - 1 - e)))
107 #define OPCODE_32BIT_INSN(word) (BITS ((word), 27, 31))
109 /* Functions implementation. */
111 /* Add a new element to the decode list. */
114 add_to_decodelist (insn_class_t insn_class,
115 insn_subclass_t subclass)
117 linkclass t = (linkclass) xmalloc (sizeof (skipclass_t));
119 t->insn_class = insn_class;
120 t->subclass = subclass;
125 /* Return TRUE if we need to skip the opcode from being
129 skip_this_opcode (const struct arc_opcode *opcode)
131 linkclass t = decodelist;
133 /* Check opcode for major 0x06, return if it is not in. */
134 if (arc_opcode_len (opcode) == 4
135 && OPCODE_32BIT_INSN (opcode->opcode) != 0x06)
138 /* or not a known truble class. */
139 switch (opcode->insn_class)
150 if ((t->insn_class == opcode->insn_class)
151 && (t->subclass == opcode->subclass))
160 bfd_getm32 (unsigned int data)
164 value = ((data & 0xff00) | (data & 0xff)) << 16;
165 value |= ((data & 0xff0000) | (data & 0xff000000)) >> 16;
170 special_flag_p (const char *opname,
173 const struct arc_flag_special *flg_spec;
174 unsigned i, j, flgidx;
176 for (i = 0; i < arc_num_flag_special; i++)
178 flg_spec = &arc_flag_special_cases[i];
180 if (strcmp (opname, flg_spec->name))
183 /* Found potential special case instruction. */
186 flgidx = flg_spec->flags[j];
188 break; /* End of the array. */
190 if (strcmp (flgname, arc_flag_operands[flgidx].name) == 0)
197 /* Find opcode from ARC_TABLE given the instruction described by INSN and
198 INSNLEN. The ISA_MASK restricts the possible matches in ARC_TABLE. */
200 static const struct arc_opcode *
201 find_format_from_table (struct disassemble_info *info,
202 const struct arc_opcode *arc_table,
203 unsigned long long insn,
204 unsigned int insn_len,
206 bfd_boolean *has_limm,
207 bfd_boolean overlaps)
210 const struct arc_opcode *opcode = NULL;
211 const struct arc_opcode *t_op = NULL;
212 const unsigned char *opidx;
213 const unsigned char *flgidx;
214 bfd_boolean warn_p = FALSE;
218 bfd_boolean invalid = FALSE;
220 opcode = &arc_table[i++];
222 if (!(opcode->cpu & isa_mask))
225 if (arc_opcode_len (opcode) != (int) insn_len)
228 if ((insn & opcode->mask) != opcode->opcode)
233 /* Possible candidate, check the operands. */
234 for (opidx = opcode->operands; *opidx; opidx++)
237 const struct arc_operand *operand = &arc_operands[*opidx];
239 if (operand->flags & ARC_OPERAND_FAKE)
242 if (operand->extract)
243 value = (*operand->extract) (insn, &invalid);
245 value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
247 /* Check for LIMM indicator. If it is there, then make sure
248 we pick the right format. */
249 limmind = (isa_mask & ARC_OPCODE_ARCV2) ? 0x1E : 0x3E;
250 if (operand->flags & ARC_OPERAND_IR
251 && !(operand->flags & ARC_OPERAND_LIMM))
253 if ((value == 0x3E && insn_len == 4)
254 || (value == limmind && insn_len == 2))
261 if (operand->flags & ARC_OPERAND_LIMM
262 && !(operand->flags & ARC_OPERAND_DUPLICATE))
266 /* Check the flags. */
267 for (flgidx = opcode->flags; *flgidx; flgidx++)
269 /* Get a valid flag class. */
270 const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
271 const unsigned *flgopridx;
272 int foundA = 0, foundB = 0;
275 /* Check first the extensions. */
276 if (cl_flags->flag_class & F_CLASS_EXTEND)
278 value = (insn & 0x1F);
279 if (arcExtMap_condCodeName (value))
283 for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
285 const struct arc_flag_operand *flg_operand =
286 &arc_flag_operands[*flgopridx];
288 value = (insn >> flg_operand->shift)
289 & ((1 << flg_operand->bits) - 1);
290 if (value == flg_operand->code)
296 if (!foundA && foundB)
311 if (skip_this_opcode (opcode))
315 /* The instruction is valid. */
318 while (opcode->mask);
322 info->fprintf_func (info->stream,
323 _("\nWarning: disassembly may be wrong due to "
324 "guessed opcode class choice.\n"
325 "Use -M<class[,class]> to select the correct "
326 "opcode class(es).\n\t\t\t\t"));
333 /* Find opcode for INSN, trying various different sources. The instruction
334 length in INSN_LEN will be updated if the instruction requires a LIMM
337 A pointer to the opcode is placed into OPCODE_RESULT, and ITER is
338 initialised, ready to iterate over the operands of the found opcode. If
339 the found opcode requires a LIMM then the LIMM value will be loaded into a
342 This function returns TRUE in almost all cases, FALSE is reserved to
343 indicate an error (failing to find an opcode is not an error) a returned
344 result of FALSE would indicate that the disassembler can't continue.
346 If no matching opcode is found then the returned result will be TRUE, the
347 value placed into OPCODE_RESULT will be NULL, ITER will be undefined, and
348 INSN_LEN will be unchanged.
350 If a matching opcode is found, then the returned result will be TRUE, the
351 opcode pointer is placed into OPCODE_RESULT, INSN_LEN will be increased by
352 4 if the instruction requires a LIMM, and the LIMM value will have been
353 loaded into a field of ITER. Finally, ITER will have been initialised so
354 that calls to OPERAND_ITERATOR_NEXT will iterate over the opcode's
358 find_format (bfd_vma memaddr,
359 unsigned long long insn,
360 unsigned int * insn_len,
362 struct disassemble_info * info,
363 const struct arc_opcode ** opcode_result,
364 struct arc_operand_iterator * iter)
366 const struct arc_opcode *opcode = NULL;
367 bfd_boolean needs_limm;
368 const extInstruction_t *einsn, *i;
371 /* First, try the extension instructions. */
374 einsn = arcExtMap_insn (OPCODE_32BIT_INSN (insn), insn);
375 for (i = einsn; (i != NULL) && (opcode == NULL); i = i->next)
377 const char *errmsg = NULL;
379 opcode = arcExtMap_genOpcode (i, isa_mask, &errmsg);
382 (*info->fprintf_func) (info->stream, "\
383 An error occured while generating the extension instruction operations");
384 *opcode_result = NULL;
388 opcode = find_format_from_table (info, opcode, insn, *insn_len,
389 isa_mask, &needs_limm, FALSE);
393 /* Then, try finding the first match in the opcode table. */
395 opcode = find_format_from_table (info, arc_opcodes, insn, *insn_len,
396 isa_mask, &needs_limm, TRUE);
398 if (needs_limm && opcode != NULL)
403 status = (*info->read_memory_func) (memaddr + *insn_len, buffer,
411 limm = ARRANGE_ENDIAN (info, buffer);
420 iter->opcode = opcode;
421 iter->opidx = opcode->operands;
424 *opcode_result = opcode;
429 print_flags (const struct arc_opcode *opcode,
430 unsigned long long *insn,
431 struct disassemble_info *info)
433 const unsigned char *flgidx;
436 /* Now extract and print the flags. */
437 for (flgidx = opcode->flags; *flgidx; flgidx++)
439 /* Get a valid flag class. */
440 const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
441 const unsigned *flgopridx;
443 /* Check first the extensions. */
444 if (cl_flags->flag_class & F_CLASS_EXTEND)
447 value = (insn[0] & 0x1F);
449 name = arcExtMap_condCodeName (value);
452 (*info->fprintf_func) (info->stream, ".%s", name);
457 for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
459 const struct arc_flag_operand *flg_operand =
460 &arc_flag_operands[*flgopridx];
462 if (!flg_operand->favail)
465 value = (insn[0] >> flg_operand->shift)
466 & ((1 << flg_operand->bits) - 1);
467 if (value == flg_operand->code)
469 /* FIXME!: print correctly nt/t flag. */
470 if (!special_flag_p (opcode->name, flg_operand->name))
471 (*info->fprintf_func) (info->stream, ".");
472 else if (info->insn_type == dis_dref)
474 switch (flg_operand->name[0])
488 if (flg_operand->name[0] == 'd'
489 && flg_operand->name[1] == 0)
490 info->branch_delay_insns = 1;
492 /* Check if it is a conditional flag. */
493 if (cl_flags->flag_class & F_CLASS_COND)
495 if (info->insn_type == dis_jsr)
496 info->insn_type = dis_condjsr;
497 else if (info->insn_type == dis_branch)
498 info->insn_type = dis_condbranch;
501 (*info->fprintf_func) (info->stream, "%s", flg_operand->name);
508 get_auxreg (const struct arc_opcode *opcode,
514 const struct arc_aux_reg *auxr = &arc_aux_regs[0];
516 if (opcode->insn_class != AUXREG)
519 name = arcExtMap_auxRegName (value);
523 for (i = 0; i < arc_num_aux_regs; i++, auxr++)
525 if (!(auxr->cpu & isa_mask))
528 if (auxr->subclass != NONE)
531 if (auxr->address == value)
537 /* Convert a value representing an address type to a string used to refer to
538 the address type in assembly code. */
541 get_addrtype (int value)
543 if (value < 0 || value > addrtypenames_max)
544 return addrtypeunknown;
546 return addrtypenames[value];
549 /* Calculate the instruction length for an instruction starting with MSB
550 and LSB, the most and least significant byte. The ISA_MASK is used to
551 filter the instructions considered to only those that are part of the
552 current architecture.
554 The instruction lengths are calculated from the ARC_OPCODE table, and
555 cached for later use. */
558 arc_insn_length (bfd_byte msb, bfd_byte lsb, struct disassemble_info *info)
560 bfd_byte major_opcode = msb >> 3;
564 case bfd_mach_arc_arc700:
565 /* The nps400 extension set requires this special casing of the
566 instruction length calculation. Right now this is not causing any
567 problems as none of the known extensions overlap in opcode space,
568 but, if they ever do then we might need to start carrying
569 information around in the elf about which extensions are in use. */
570 if (major_opcode == 0xb)
572 bfd_byte minor_opcode = lsb & 0x1f;
574 if (minor_opcode < 4)
576 else if (minor_opcode == 0x10 || minor_opcode == 0x11)
579 if (major_opcode == 0xa)
584 case bfd_mach_arc_arc600:
585 return (major_opcode > 0xb) ? 2 : 4;
588 case bfd_mach_arc_arcv2:
589 return (major_opcode > 0x7) ? 2 : 4;
597 /* Extract and return the value of OPERAND from the instruction whose value
598 is held in the array INSN. */
601 extract_operand_value (const struct arc_operand *operand,
602 unsigned long long insn,
607 /* Read the limm operand, if required. */
608 if (operand->flags & ARC_OPERAND_LIMM)
609 /* The second part of the instruction value will have been loaded as
610 part of the find_format call made earlier. */
614 if (operand->extract)
615 value = (*operand->extract) (insn, (int *) NULL);
618 if (operand->flags & ARC_OPERAND_ALIGNED32)
620 value = (insn >> operand->shift)
621 & ((1 << (operand->bits - 2)) - 1);
626 value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
628 if (operand->flags & ARC_OPERAND_SIGNED)
630 int signbit = 1 << (operand->bits - 1);
631 value = (value ^ signbit) - signbit;
639 /* Find the next operand, and the operands value from ITER. Return TRUE if
640 there is another operand, otherwise return FALSE. If there is an
641 operand returned then the operand is placed into OPERAND, and the value
642 into VALUE. If there is no operand returned then OPERAND and VALUE are
646 operand_iterator_next (struct arc_operand_iterator *iter,
647 const struct arc_operand **operand,
650 if (*iter->opidx == 0)
656 *operand = &arc_operands[*iter->opidx];
657 *value = extract_operand_value (*operand, iter->insn, iter->limm);
663 /* Helper for parsing the options. */
666 parse_option (char *option)
668 if (CONST_STRNEQ (option, "dsp"))
669 add_to_decodelist (DSP, NONE);
671 else if (CONST_STRNEQ (option, "spfp"))
672 add_to_decodelist (FLOAT, SPX);
674 else if (CONST_STRNEQ (option, "dpfp"))
675 add_to_decodelist (FLOAT, DPX);
677 else if (CONST_STRNEQ (option, "quarkse_em"))
679 add_to_decodelist (FLOAT, DPX);
680 add_to_decodelist (FLOAT, SPX);
681 add_to_decodelist (FLOAT, QUARKSE);
684 else if (CONST_STRNEQ (option, "fpuda"))
685 add_to_decodelist (FLOAT, DPA);
687 else if (CONST_STRNEQ (option, "fpus"))
689 add_to_decodelist (FLOAT, SP);
690 add_to_decodelist (FLOAT, CVT);
693 else if (CONST_STRNEQ (option, "fpud"))
695 add_to_decodelist (FLOAT, DP);
696 add_to_decodelist (FLOAT, CVT);
699 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
702 /* Go over the options list and parse it. */
705 parse_disassembler_options (char *options)
712 /* Skip empty options. */
719 parse_option (options);
721 while (*options != ',' && *options != '\0')
726 /* Return the instruction type for an instruction described by OPCODE. */
728 static enum dis_insn_type
729 arc_opcode_to_insn_type (const struct arc_opcode *opcode)
731 enum dis_insn_type insn_type;
733 switch (opcode->insn_class)
737 if (!strncmp (opcode->name, "bl", 2)
738 || !strncmp (opcode->name, "jl", 2))
740 if (opcode->subclass == COND)
741 insn_type = dis_condjsr;
747 if (opcode->subclass == COND)
748 insn_type = dis_condbranch;
750 insn_type = dis_branch;
756 insn_type = dis_dref;
759 insn_type = dis_nonbranch;
766 /* Disassemble ARC instructions. */
769 print_insn_arc (bfd_vma memaddr,
770 struct disassemble_info *info)
773 unsigned int highbyte, lowbyte;
775 unsigned int insn_len;
776 unsigned long long insn = 0;
778 const struct arc_opcode *opcode;
779 bfd_boolean need_comma;
780 bfd_boolean open_braket;
782 const struct arc_operand *operand;
784 struct arc_operand_iterator iter;
785 Elf_Internal_Ehdr *header = NULL;
787 if (info->disassembler_options)
789 parse_disassembler_options (info->disassembler_options);
791 /* Avoid repeated parsing of the options. */
792 info->disassembler_options = NULL;
795 memset (&iter, 0, sizeof (iter));
796 highbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 1 : 0);
797 lowbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 0 : 1);
799 if (info->section && info->section->owner)
800 header = elf_elfheader (info->section->owner);
804 case bfd_mach_arc_arc700:
805 isa_mask = ARC_OPCODE_ARC700;
808 case bfd_mach_arc_arc600:
809 isa_mask = ARC_OPCODE_ARC600;
812 case bfd_mach_arc_arcv2:
814 isa_mask = ARC_OPCODE_ARCv2EM;
815 /* TODO: Perhaps remove defitinion of header since it is only used at
818 && (header->e_flags & EF_ARC_MACH_MSK) == EF_ARC_CPU_ARCV2HS)
820 isa_mask = ARC_OPCODE_ARCv2HS;
821 /* FPU instructions are not extensions for HS. */
822 add_to_decodelist (FLOAT, SP);
823 add_to_decodelist (FLOAT, DP);
824 add_to_decodelist (FLOAT, CVT);
829 /* This variable may be set by the instruction decoder. It suggests
830 the number of bytes objdump should display on a single line. If
831 the instruction decoder sets this, it should always set it to
832 the same value in order to get reasonable looking output. */
834 info->bytes_per_line = 8;
836 /* In the next lines, we set two info variables control the way
837 objdump displays the raw data. For example, if bytes_per_line is
838 8 and bytes_per_chunk is 4, the output will look like this:
839 00: 00000000 00000000
840 with the chunks displayed according to "display_endian". */
843 && !(info->section->flags & SEC_CODE))
845 /* This is not a CODE section. */
846 switch (info->section->size)
851 size = info->section->size;
854 size = (info->section->size & 0x01) ? 1 : 4;
857 info->bytes_per_chunk = 1;
858 info->display_endian = info->endian;
863 info->bytes_per_chunk = 2;
864 info->display_endian = info->endian;
867 /* Read the insn into a host word. */
868 status = (*info->read_memory_func) (memaddr, buffer, size, info);
871 (*info->memory_error_func) (status, memaddr, info);
876 && !(info->section->flags & SEC_CODE))
881 data = bfd_get_bits (buffer, size * 8,
882 info->display_endian == BFD_ENDIAN_BIG);
886 (*info->fprintf_func) (info->stream, ".byte\t0x%02lx", data);
889 (*info->fprintf_func) (info->stream, ".short\t0x%04lx", data);
892 (*info->fprintf_func) (info->stream, ".word\t0x%08lx", data);
900 insn_len = arc_insn_length (buffer[highbyte], buffer[lowbyte], info);
901 pr_debug ("instruction length = %d bytes\n", insn_len);
906 insn = (buffer[highbyte] << 8) | buffer[lowbyte];
911 /* This is a long instruction: Read the remaning 2 bytes. */
912 status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 2, info);
915 (*info->memory_error_func) (status, memaddr + 2, info);
918 insn = (unsigned long long) ARRANGE_ENDIAN (info, buffer);
924 status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 4, info);
927 (*info->memory_error_func) (status, memaddr + 2, info);
930 insn = (unsigned long long) ARRANGE_ENDIAN (info, &buffer[2]);
931 insn |= ((unsigned long long) buffer[highbyte] << 40)
932 | ((unsigned long long) buffer[lowbyte] << 32);
938 status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 6, info);
941 (*info->memory_error_func) (status, memaddr + 2, info);
945 ((((unsigned long long) ARRANGE_ENDIAN (info, buffer)) << 32)
946 | ((unsigned long long) ARRANGE_ENDIAN (info, &buffer[4])));
951 /* There is no instruction whose length is not 2, 4, 6, or 8. */
955 pr_debug ("instruction value = %llx\n", insn);
957 /* Set some defaults for the insn info. */
958 info->insn_info_valid = 1;
959 info->branch_delay_insns = 0;
961 info->insn_type = dis_nonbranch;
965 /* FIXME to be moved in dissasemble_init_for_target. */
966 info->disassembler_needs_relocs = TRUE;
968 /* Find the first match in the opcode table. */
969 if (!find_format (memaddr, insn, &insn_len, isa_mask, info, &opcode, &iter))
977 (*info->fprintf_func) (info->stream, ".long %#04llx",
981 (*info->fprintf_func) (info->stream, ".long %#08llx",
985 (*info->fprintf_func) (info->stream, ".long %#08llx",
987 (*info->fprintf_func) (info->stream, ".long %#04llx",
988 (insn >> 32) & 0xffff);
991 (*info->fprintf_func) (info->stream, ".long %#08llx",
993 (*info->fprintf_func) (info->stream, ".long %#08llx",
1000 info->insn_type = dis_noninsn;
1004 /* Print the mnemonic. */
1005 (*info->fprintf_func) (info->stream, "%s", opcode->name);
1007 /* Preselect the insn class. */
1008 info->insn_type = arc_opcode_to_insn_type (opcode);
1010 pr_debug ("%s: 0x%08llx\n", opcode->name, opcode->opcode);
1012 print_flags (opcode, &insn, info);
1014 if (opcode->operands[0] != 0)
1015 (*info->fprintf_func) (info->stream, "\t");
1018 open_braket = FALSE;
1020 /* Now extract and print the operands. */
1022 while (operand_iterator_next (&iter, &operand, &value))
1024 if (open_braket && (operand->flags & ARC_OPERAND_BRAKET))
1026 (*info->fprintf_func) (info->stream, "]");
1027 open_braket = FALSE;
1031 /* Only take input from real operands. */
1032 if (ARC_OPERAND_IS_FAKE (operand))
1035 if ((operand->flags & ARC_OPERAND_IGNORE)
1036 && (operand->flags & ARC_OPERAND_IR)
1040 if (operand->flags & ARC_OPERAND_COLON)
1042 (*info->fprintf_func) (info->stream, ":");
1047 (*info->fprintf_func) (info->stream, ",");
1049 if (!open_braket && (operand->flags & ARC_OPERAND_BRAKET))
1051 (*info->fprintf_func) (info->stream, "[");
1059 /* Print the operand as directed by the flags. */
1060 if (operand->flags & ARC_OPERAND_IR)
1064 assert (value >=0 && value < 64);
1065 rname = arcExtMap_coreRegName (value);
1067 rname = regnames[value];
1068 (*info->fprintf_func) (info->stream, "%s", rname);
1069 if (operand->flags & ARC_OPERAND_TRUNCATE)
1071 rname = arcExtMap_coreRegName (value + 1);
1073 rname = regnames[value + 1];
1074 (*info->fprintf_func) (info->stream, "%s", rname);
1077 else if (operand->flags & ARC_OPERAND_LIMM)
1079 const char *rname = get_auxreg (opcode, value, isa_mask);
1081 if (rname && open_braket)
1082 (*info->fprintf_func) (info->stream, "%s", rname);
1085 (*info->fprintf_func) (info->stream, "%#x", value);
1086 if (info->insn_type == dis_branch
1087 || info->insn_type == dis_jsr)
1088 info->target = (bfd_vma) value;
1091 else if (operand->flags & ARC_OPERAND_PCREL)
1094 if (info->flags & INSN_HAS_RELOC)
1096 (*info->print_address_func) ((memaddr & ~3) + value, info);
1098 info->target = (bfd_vma) (memaddr & ~3) + value;
1100 else if (operand->flags & ARC_OPERAND_SIGNED)
1102 const char *rname = get_auxreg (opcode, value, isa_mask);
1103 if (rname && open_braket)
1104 (*info->fprintf_func) (info->stream, "%s", rname);
1106 (*info->fprintf_func) (info->stream, "%d", value);
1108 else if (operand->flags & ARC_OPERAND_ADDRTYPE)
1110 const char *addrtype = get_addrtype (value);
1111 (*info->fprintf_func) (info->stream, "%s", addrtype);
1112 /* A colon follow an address type. */
1117 if (operand->flags & ARC_OPERAND_TRUNCATE
1118 && !(operand->flags & ARC_OPERAND_ALIGNED32)
1119 && !(operand->flags & ARC_OPERAND_ALIGNED16)
1120 && value > 0 && value <= 14)
1121 (*info->fprintf_func) (info->stream, "r13-%s",
1122 regnames[13 + value - 1]);
1125 const char *rname = get_auxreg (opcode, value, isa_mask);
1126 if (rname && open_braket)
1127 (*info->fprintf_func) (info->stream, "%s", rname);
1129 (*info->fprintf_func) (info->stream, "%#x", value);
1139 arc_get_disassembler (bfd *abfd)
1141 /* BFD my be absent, if opcodes is invoked from the debugger that
1142 has connected to remote target and doesn't have an ELF file. */
1145 /* Read the extension insns and registers, if any. */
1146 build_ARC_extmap (abfd);
1152 return print_insn_arc;
1155 /* Disassemble ARC instructions. Used by debugger. */
1158 arcAnalyzeInstr (bfd_vma memaddr,
1159 struct disassemble_info *info)
1161 struct arcDisState ret;
1162 memset (&ret, 0, sizeof (struct arcDisState));
1164 ret.instructionLen = print_insn_arc (memaddr, info);
1167 ret.words[0] = insn[0];
1168 ret.words[1] = insn[1];
1170 ret.coreRegName = _coreRegName;
1171 ret.auxRegName = _auxRegName;
1172 ret.condCodeName = _condCodeName;
1173 ret.instName = _instName;
1180 print_arc_disassembler_options (FILE *stream)
1182 fprintf (stream, _("\n\
1183 The following ARC specific disassembler options are supported for use \n\
1184 with -M switch (multiple options should be separated by commas):\n"));
1186 fprintf (stream, _("\
1187 dsp Recognize DSP instructions.\n"));
1188 fprintf (stream, _("\
1189 spfp Recognize FPX SP instructions.\n"));
1190 fprintf (stream, _("\
1191 dpfp Recognize FPX DP instructions.\n"));
1192 fprintf (stream, _("\
1193 quarkse_em Recognize FPU QuarkSE-EM instructions.\n"));
1194 fprintf (stream, _("\
1195 fpuda Recognize double assist FPU instructions.\n"));
1196 fprintf (stream, _("\
1197 fpus Recognize single precision FPU instructions.\n"));
1198 fprintf (stream, _("\
1199 fpud Recognize double precision FPU instructions.\n"));
1204 eval: (c-set-style "gnu")