1 /* Instruction printing code for the ARC.
2 Copyright (C) 1994-2016 Free Software Foundation, Inc.
4 Contributed by Claudiu Zissulescu (claziss@synopsys.com)
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 /* Return TRUE when two classes are not opcode conflicting. */
114 is_compatible_p (insn_class_t classA
,
115 insn_subclass_t sclassA
,
117 insn_subclass_t sclassB
)
119 if (classA
== DSP
&& sclassB
== DPX
)
121 if (sclassA
== DPX
&& classB
== DSP
)
126 /* Add a new element to the decode list. */
129 add_to_decodelist (insn_class_t insn_class
,
130 insn_subclass_t subclass
)
132 linkclass t
= (linkclass
) xmalloc (sizeof (skipclass_t
));
134 t
->insn_class
= insn_class
;
135 t
->subclass
= subclass
;
140 /* Return TRUE if we need to skip the opcode from being
144 skip_this_opcode (const struct arc_opcode
* opcode
,
145 struct disassemble_info
* info
)
147 linkclass t
= decodelist
;
148 bfd_boolean addme
= TRUE
;
150 /* Check opcode for major 0x06, return if it is not in. */
151 if (arc_opcode_len (opcode
) == 4
152 && OPCODE_32BIT_INSN (opcode
->opcode
) != 0x06)
156 && is_compatible_p (t
->insn_class
, t
->subclass
,
157 opcode
->insn_class
, opcode
->subclass
))
159 if ((t
->insn_class
== opcode
->insn_class
)
160 && (t
->subclass
== opcode
->subclass
))
165 /* If we found an incompatibility then we must skip. */
169 /* Even if we do not precisely know the if the right mnemonics
170 is correctly displayed, keep the disassmbled code class
174 switch (opcode
->insn_class
)
178 /* Add to the conflict list only the classes which
180 add_to_decodelist (opcode
->insn_class
, opcode
->subclass
);
181 /* Warn if we have to decode an opcode and no preferred
182 classes have been chosen. */
183 info
->fprintf_func (info
->stream
, _("\n\
184 Warning: disassembly may be wrong due to guessed opcode class choice.\n\
185 Use -M<class[,class]> to select the correct opcode class(es).\n\t\t\t\t"));
195 bfd_getm32 (unsigned int data
)
199 value
= ((data
& 0xff00) | (data
& 0xff)) << 16;
200 value
|= ((data
& 0xff0000) | (data
& 0xff000000)) >> 16;
205 special_flag_p (const char *opname
,
208 const struct arc_flag_special
*flg_spec
;
209 unsigned i
, j
, flgidx
;
211 for (i
= 0; i
< arc_num_flag_special
; i
++)
213 flg_spec
= &arc_flag_special_cases
[i
];
215 if (strcmp (opname
, flg_spec
->name
))
218 /* Found potential special case instruction. */
221 flgidx
= flg_spec
->flags
[j
];
223 break; /* End of the array. */
225 if (strcmp (flgname
, arc_flag_operands
[flgidx
].name
) == 0)
232 /* Find opcode from ARC_TABLE given the instruction described by INSN and
233 INSNLEN. The ISA_MASK restricts the possible matches in ARC_TABLE. */
235 static const struct arc_opcode
*
236 find_format_from_table (struct disassemble_info
*info
,
237 const struct arc_opcode
*arc_table
,
238 unsigned long long insn
,
239 unsigned int insn_len
,
241 bfd_boolean
*has_limm
,
242 bfd_boolean overlaps
)
245 const struct arc_opcode
*opcode
= NULL
;
246 const unsigned char *opidx
;
247 const unsigned char *flgidx
;
251 bfd_boolean invalid
= FALSE
;
253 opcode
= &arc_table
[i
++];
255 if (!(opcode
->cpu
& isa_mask
))
258 if (arc_opcode_len (opcode
) != (int) insn_len
)
261 if ((insn
& opcode
->mask
) != opcode
->opcode
)
266 /* Possible candidate, check the operands. */
267 for (opidx
= opcode
->operands
; *opidx
; opidx
++)
270 const struct arc_operand
*operand
= &arc_operands
[*opidx
];
272 if (operand
->flags
& ARC_OPERAND_FAKE
)
275 if (operand
->extract
)
276 value
= (*operand
->extract
) (insn
, &invalid
);
278 value
= (insn
>> operand
->shift
) & ((1 << operand
->bits
) - 1);
280 /* Check for LIMM indicator. If it is there, then make sure
281 we pick the right format. */
282 limmind
= (isa_mask
& ARC_OPCODE_ARCV2
) ? 0x1E : 0x3E;
283 if (operand
->flags
& ARC_OPERAND_IR
284 && !(operand
->flags
& ARC_OPERAND_LIMM
))
286 if ((value
== 0x3E && insn_len
== 4)
287 || (value
== limmind
&& insn_len
== 2))
294 if (operand
->flags
& ARC_OPERAND_LIMM
295 && !(operand
->flags
& ARC_OPERAND_DUPLICATE
))
299 /* Check the flags. */
300 for (flgidx
= opcode
->flags
; *flgidx
; flgidx
++)
302 /* Get a valid flag class. */
303 const struct arc_flag_class
*cl_flags
= &arc_flag_classes
[*flgidx
];
304 const unsigned *flgopridx
;
305 int foundA
= 0, foundB
= 0;
308 /* Check first the extensions. */
309 if (cl_flags
->flag_class
& F_CLASS_EXTEND
)
311 value
= (insn
& 0x1F);
312 if (arcExtMap_condCodeName (value
))
316 for (flgopridx
= cl_flags
->flags
; *flgopridx
; ++flgopridx
)
318 const struct arc_flag_operand
*flg_operand
=
319 &arc_flag_operands
[*flgopridx
];
321 value
= (insn
>> flg_operand
->shift
)
322 & ((1 << flg_operand
->bits
) - 1);
323 if (value
== flg_operand
->code
)
329 if (!foundA
&& foundB
)
341 && skip_this_opcode (opcode
, info
))
344 /* The instruction is valid. */
347 while (opcode
->mask
);
352 /* Find opcode for INSN, trying various different sources. The instruction
353 length in INSN_LEN will be updated if the instruction requires a LIMM
356 A pointer to the opcode is placed into OPCODE_RESULT, and ITER is
357 initialised, ready to iterate over the operands of the found opcode. If
358 the found opcode requires a LIMM then the LIMM value will be loaded into a
361 This function returns TRUE in almost all cases, FALSE is reserved to
362 indicate an error (failing to find an opcode is not an error) a returned
363 result of FALSE would indicate that the disassembler can't continue.
365 If no matching opcode is found then the returned result will be TRUE, the
366 value placed into OPCODE_RESULT will be NULL, ITER will be undefined, and
367 INSN_LEN will be unchanged.
369 If a matching opcode is found, then the returned result will be TRUE, the
370 opcode pointer is placed into OPCODE_RESULT, INSN_LEN will be increased by
371 4 if the instruction requires a LIMM, and the LIMM value will have been
372 loaded into a field of ITER. Finally, ITER will have been initialised so
373 that calls to OPERAND_ITERATOR_NEXT will iterate over the opcode's
377 find_format (bfd_vma memaddr
,
378 unsigned long long insn
,
379 unsigned int * insn_len
,
381 struct disassemble_info
* info
,
382 const struct arc_opcode
** opcode_result
,
383 struct arc_operand_iterator
* iter
)
385 const struct arc_opcode
*opcode
= NULL
;
386 bfd_boolean needs_limm
;
387 const extInstruction_t
*einsn
, *i
;
390 /* First, try the extension instructions. */
393 einsn
= arcExtMap_insn (OPCODE_32BIT_INSN (insn
), insn
);
394 for (i
= einsn
; (i
!= NULL
) && (opcode
== NULL
); i
= i
->next
)
396 const char *errmsg
= NULL
;
398 opcode
= arcExtMap_genOpcode (i
, isa_mask
, &errmsg
);
401 (*info
->fprintf_func
) (info
->stream
, "\
402 An error occured while generating the extension instruction operations");
403 *opcode_result
= NULL
;
407 opcode
= find_format_from_table (info
, opcode
, insn
, *insn_len
,
408 isa_mask
, &needs_limm
, FALSE
);
412 /* Then, try finding the first match in the opcode table. */
414 opcode
= find_format_from_table (info
, arc_opcodes
, insn
, *insn_len
,
415 isa_mask
, &needs_limm
, TRUE
);
417 if (needs_limm
&& opcode
!= NULL
)
422 status
= (*info
->read_memory_func
) (memaddr
+ *insn_len
, buffer
,
430 limm
= ARRANGE_ENDIAN (info
, buffer
);
439 iter
->opcode
= opcode
;
440 iter
->opidx
= opcode
->operands
;
443 *opcode_result
= opcode
;
448 print_flags (const struct arc_opcode
*opcode
,
449 unsigned long long *insn
,
450 struct disassemble_info
*info
)
452 const unsigned char *flgidx
;
455 /* Now extract and print the flags. */
456 for (flgidx
= opcode
->flags
; *flgidx
; flgidx
++)
458 /* Get a valid flag class. */
459 const struct arc_flag_class
*cl_flags
= &arc_flag_classes
[*flgidx
];
460 const unsigned *flgopridx
;
462 /* Check first the extensions. */
463 if (cl_flags
->flag_class
& F_CLASS_EXTEND
)
466 value
= (insn
[0] & 0x1F);
468 name
= arcExtMap_condCodeName (value
);
471 (*info
->fprintf_func
) (info
->stream
, ".%s", name
);
476 for (flgopridx
= cl_flags
->flags
; *flgopridx
; ++flgopridx
)
478 const struct arc_flag_operand
*flg_operand
=
479 &arc_flag_operands
[*flgopridx
];
481 if (!flg_operand
->favail
)
484 value
= (insn
[0] >> flg_operand
->shift
)
485 & ((1 << flg_operand
->bits
) - 1);
486 if (value
== flg_operand
->code
)
488 /* FIXME!: print correctly nt/t flag. */
489 if (!special_flag_p (opcode
->name
, flg_operand
->name
))
490 (*info
->fprintf_func
) (info
->stream
, ".");
491 else if (info
->insn_type
== dis_dref
)
493 switch (flg_operand
->name
[0])
507 if (flg_operand
->name
[0] == 'd'
508 && flg_operand
->name
[1] == 0)
509 info
->branch_delay_insns
= 1;
511 /* Check if it is a conditional flag. */
512 if (cl_flags
->flag_class
& F_CLASS_COND
)
514 if (info
->insn_type
== dis_jsr
)
515 info
->insn_type
= dis_condjsr
;
516 else if (info
->insn_type
== dis_branch
)
517 info
->insn_type
= dis_condbranch
;
520 (*info
->fprintf_func
) (info
->stream
, "%s", flg_operand
->name
);
527 get_auxreg (const struct arc_opcode
*opcode
,
533 const struct arc_aux_reg
*auxr
= &arc_aux_regs
[0];
535 if (opcode
->insn_class
!= AUXREG
)
538 name
= arcExtMap_auxRegName (value
);
542 for (i
= 0; i
< arc_num_aux_regs
; i
++, auxr
++)
544 if (!(auxr
->cpu
& isa_mask
))
547 if (auxr
->subclass
!= NONE
)
550 if (auxr
->address
== value
)
556 /* Convert a value representing an address type to a string used to refer to
557 the address type in assembly code. */
560 get_addrtype (int value
)
562 if (value
< 0 || value
> addrtypenames_max
)
563 return addrtypeunknown
;
565 return addrtypenames
[value
];
568 /* Calculate the instruction length for an instruction starting with MSB
569 and LSB, the most and least significant byte. The ISA_MASK is used to
570 filter the instructions considered to only those that are part of the
571 current architecture.
573 The instruction lengths are calculated from the ARC_OPCODE table, and
574 cached for later use. */
577 arc_insn_length (bfd_byte msb
, bfd_byte lsb
, struct disassemble_info
*info
)
579 bfd_byte major_opcode
= msb
>> 3;
583 case bfd_mach_arc_arc700
:
584 /* The nps400 extension set requires this special casing of the
585 instruction length calculation. Right now this is not causing any
586 problems as none of the known extensions overlap in opcode space,
587 but, if they ever do then we might need to start carrying
588 information around in the elf about which extensions are in use. */
589 if (major_opcode
== 0xb)
591 bfd_byte minor_opcode
= lsb
& 0x1f;
593 if (minor_opcode
< 4)
595 else if (minor_opcode
== 0x10 || minor_opcode
== 0x11)
598 if (major_opcode
== 0xa)
603 case bfd_mach_arc_arc600
:
604 return (major_opcode
> 0xb) ? 2 : 4;
607 case bfd_mach_arc_arcv2
:
608 return (major_opcode
> 0x7) ? 2 : 4;
616 /* Extract and return the value of OPERAND from the instruction whose value
617 is held in the array INSN. */
620 extract_operand_value (const struct arc_operand
*operand
,
621 unsigned long long insn
,
626 /* Read the limm operand, if required. */
627 if (operand
->flags
& ARC_OPERAND_LIMM
)
628 /* The second part of the instruction value will have been loaded as
629 part of the find_format call made earlier. */
633 if (operand
->extract
)
634 value
= (*operand
->extract
) (insn
, (int *) NULL
);
637 if (operand
->flags
& ARC_OPERAND_ALIGNED32
)
639 value
= (insn
>> operand
->shift
)
640 & ((1 << (operand
->bits
- 2)) - 1);
645 value
= (insn
>> operand
->shift
) & ((1 << operand
->bits
) - 1);
647 if (operand
->flags
& ARC_OPERAND_SIGNED
)
649 int signbit
= 1 << (operand
->bits
- 1);
650 value
= (value
^ signbit
) - signbit
;
658 /* Find the next operand, and the operands value from ITER. Return TRUE if
659 there is another operand, otherwise return FALSE. If there is an
660 operand returned then the operand is placed into OPERAND, and the value
661 into VALUE. If there is no operand returned then OPERAND and VALUE are
665 operand_iterator_next (struct arc_operand_iterator
*iter
,
666 const struct arc_operand
**operand
,
669 if (*iter
->opidx
== 0)
675 *operand
= &arc_operands
[*iter
->opidx
];
676 *value
= extract_operand_value (*operand
, iter
->insn
, iter
->limm
);
682 /* Helper for parsing the options. */
685 parse_option (char *option
)
687 if (CONST_STRNEQ (option
, "dsp"))
688 add_to_decodelist (DSP
, NONE
);
690 else if (CONST_STRNEQ (option
, "spfp"))
691 add_to_decodelist (FLOAT
, SPX
);
693 else if (CONST_STRNEQ (option
, "dpfp"))
694 add_to_decodelist (FLOAT
, DPX
);
696 else if (CONST_STRNEQ (option
, "quarkse_em"))
697 add_to_decodelist (FLOAT
, QUARKSE
);
699 else if (CONST_STRNEQ (option
, "fpuda"))
700 add_to_decodelist (FLOAT
, DPA
);
702 else if (CONST_STRNEQ (option
, "fpud"))
704 add_to_decodelist (FLOAT
, SP
);
705 add_to_decodelist (FLOAT
, CVT
);
708 else if (CONST_STRNEQ (option
, "fpus"))
710 add_to_decodelist (FLOAT
, DP
);
711 add_to_decodelist (FLOAT
, CVT
);
714 fprintf (stderr
, _("Unrecognised disassembler option: %s\n"), option
);
717 /* Go over the options list and parse it. */
720 parse_disassembler_options (char *options
)
727 /* Skip empty options. */
734 parse_option (options
);
736 while (*options
!= ',' && *options
!= '\0')
741 /* Return the instruction type for an instruction described by OPCODE. */
743 static enum dis_insn_type
744 arc_opcode_to_insn_type (const struct arc_opcode
*opcode
)
746 enum dis_insn_type insn_type
;
748 switch (opcode
->insn_class
)
752 if (!strncmp (opcode
->name
, "bl", 2)
753 || !strncmp (opcode
->name
, "jl", 2))
755 if (opcode
->subclass
== COND
)
756 insn_type
= dis_condjsr
;
762 if (opcode
->subclass
== COND
)
763 insn_type
= dis_condbranch
;
765 insn_type
= dis_branch
;
769 insn_type
= dis_dref
; /* FIXME! DB indicates mov as memory! */
772 insn_type
= dis_nonbranch
;
779 /* Disassemble ARC instructions. */
782 print_insn_arc (bfd_vma memaddr
,
783 struct disassemble_info
*info
)
786 unsigned int highbyte
, lowbyte
;
788 unsigned int insn_len
;
789 unsigned long long insn
= 0;
791 const struct arc_opcode
*opcode
;
792 bfd_boolean need_comma
;
793 bfd_boolean open_braket
;
795 const struct arc_operand
*operand
;
797 struct arc_operand_iterator iter
;
798 Elf_Internal_Ehdr
*header
= NULL
;
800 if (info
->disassembler_options
)
802 parse_disassembler_options (info
->disassembler_options
);
804 /* Avoid repeated parsing of the options. */
805 info
->disassembler_options
= NULL
;
808 memset (&iter
, 0, sizeof (iter
));
809 highbyte
= ((info
->endian
== BFD_ENDIAN_LITTLE
) ? 1 : 0);
810 lowbyte
= ((info
->endian
== BFD_ENDIAN_LITTLE
) ? 0 : 1);
812 if (info
->section
&& info
->section
->owner
)
813 header
= elf_elfheader (info
->section
->owner
);
817 case bfd_mach_arc_arc700
:
818 isa_mask
= ARC_OPCODE_ARC700
;
821 case bfd_mach_arc_arc600
:
822 isa_mask
= ARC_OPCODE_ARC600
;
825 case bfd_mach_arc_arcv2
:
827 isa_mask
= ARC_OPCODE_ARCv2EM
;
828 /* TODO: Perhaps remove defitinion of header since it is only used at
831 && (header
->e_flags
& EF_ARC_MACH_MSK
) == EF_ARC_CPU_ARCV2HS
)
833 isa_mask
= ARC_OPCODE_ARCv2HS
;
834 /* FPU instructions are not extensions for HS. */
835 add_to_decodelist (FLOAT
, SP
);
836 add_to_decodelist (FLOAT
, DP
);
837 add_to_decodelist (FLOAT
, CVT
);
842 /* This variable may be set by the instruction decoder. It suggests
843 the number of bytes objdump should display on a single line. If
844 the instruction decoder sets this, it should always set it to
845 the same value in order to get reasonable looking output. */
847 info
->bytes_per_line
= 8;
849 /* In the next lines, we set two info variables control the way
850 objdump displays the raw data. For example, if bytes_per_line is
851 8 and bytes_per_chunk is 4, the output will look like this:
852 00: 00000000 00000000
853 with the chunks displayed according to "display_endian". */
856 && !(info
->section
->flags
& SEC_CODE
))
858 /* This is not a CODE section. */
859 switch (info
->section
->size
)
864 size
= info
->section
->size
;
867 size
= (info
->section
->size
& 0x01) ? 1 : 4;
870 info
->bytes_per_chunk
= 1;
871 info
->display_endian
= info
->endian
;
876 info
->bytes_per_chunk
= 2;
877 info
->display_endian
= info
->endian
;
880 /* Read the insn into a host word. */
881 status
= (*info
->read_memory_func
) (memaddr
, buffer
, size
, info
);
884 (*info
->memory_error_func
) (status
, memaddr
, info
);
889 && !(info
->section
->flags
& SEC_CODE
))
894 data
= bfd_get_bits (buffer
, size
* 8,
895 info
->display_endian
== BFD_ENDIAN_BIG
);
899 (*info
->fprintf_func
) (info
->stream
, ".byte\t0x%02lx", data
);
902 (*info
->fprintf_func
) (info
->stream
, ".short\t0x%04lx", data
);
905 (*info
->fprintf_func
) (info
->stream
, ".word\t0x%08lx", data
);
913 insn_len
= arc_insn_length (buffer
[highbyte
], buffer
[lowbyte
], info
);
914 pr_debug ("instruction length = %d bytes\n", insn_len
);
919 insn
= (buffer
[highbyte
] << 8) | buffer
[lowbyte
];
924 /* This is a long instruction: Read the remaning 2 bytes. */
925 status
= (*info
->read_memory_func
) (memaddr
+ 2, &buffer
[2], 2, info
);
928 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
931 insn
= (unsigned long long) ARRANGE_ENDIAN (info
, buffer
);
937 status
= (*info
->read_memory_func
) (memaddr
+ 2, &buffer
[2], 4, info
);
940 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
943 insn
= (unsigned long long) ARRANGE_ENDIAN (info
, &buffer
[2]);
944 insn
|= ((unsigned long long) buffer
[highbyte
] << 40)
945 | ((unsigned long long) buffer
[lowbyte
] << 32);
951 status
= (*info
->read_memory_func
) (memaddr
+ 2, &buffer
[2], 6, info
);
954 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
958 ((((unsigned long long) ARRANGE_ENDIAN (info
, buffer
)) << 32)
959 | ((unsigned long long) ARRANGE_ENDIAN (info
, &buffer
[4])));
964 /* There is no instruction whose length is not 2, 4, 6, or 8. */
968 pr_debug ("instruction value = %llx\n", insn
);
970 /* Set some defaults for the insn info. */
971 info
->insn_info_valid
= 1;
972 info
->branch_delay_insns
= 0;
974 info
->insn_type
= dis_nonbranch
;
978 /* FIXME to be moved in dissasemble_init_for_target. */
979 info
->disassembler_needs_relocs
= TRUE
;
981 /* Find the first match in the opcode table. */
982 if (!find_format (memaddr
, insn
, &insn_len
, isa_mask
, info
, &opcode
, &iter
))
990 (*info
->fprintf_func
) (info
->stream
, ".long %#04llx",
994 (*info
->fprintf_func
) (info
->stream
, ".long %#08llx",
998 (*info
->fprintf_func
) (info
->stream
, ".long %#08llx",
1000 (*info
->fprintf_func
) (info
->stream
, ".long %#04llx",
1001 (insn
>> 32) & 0xffff);
1004 (*info
->fprintf_func
) (info
->stream
, ".long %#08llx",
1006 (*info
->fprintf_func
) (info
->stream
, ".long %#08llx",
1013 info
->insn_type
= dis_noninsn
;
1017 /* Print the mnemonic. */
1018 (*info
->fprintf_func
) (info
->stream
, "%s", opcode
->name
);
1020 /* Preselect the insn class. */
1021 info
->insn_type
= arc_opcode_to_insn_type (opcode
);
1023 pr_debug ("%s: 0x%08llx\n", opcode
->name
, opcode
->opcode
);
1025 print_flags (opcode
, &insn
, info
);
1027 if (opcode
->operands
[0] != 0)
1028 (*info
->fprintf_func
) (info
->stream
, "\t");
1031 open_braket
= FALSE
;
1033 /* Now extract and print the operands. */
1035 while (operand_iterator_next (&iter
, &operand
, &value
))
1037 if (open_braket
&& (operand
->flags
& ARC_OPERAND_BRAKET
))
1039 (*info
->fprintf_func
) (info
->stream
, "]");
1040 open_braket
= FALSE
;
1044 /* Only take input from real operands. */
1045 if (ARC_OPERAND_IS_FAKE (operand
))
1048 if ((operand
->flags
& ARC_OPERAND_IGNORE
)
1049 && (operand
->flags
& ARC_OPERAND_IR
)
1053 if (operand
->flags
& ARC_OPERAND_COLON
)
1055 (*info
->fprintf_func
) (info
->stream
, ":");
1060 (*info
->fprintf_func
) (info
->stream
, ",");
1062 if (!open_braket
&& (operand
->flags
& ARC_OPERAND_BRAKET
))
1064 (*info
->fprintf_func
) (info
->stream
, "[");
1072 /* Print the operand as directed by the flags. */
1073 if (operand
->flags
& ARC_OPERAND_IR
)
1077 assert (value
>=0 && value
< 64);
1078 rname
= arcExtMap_coreRegName (value
);
1080 rname
= regnames
[value
];
1081 (*info
->fprintf_func
) (info
->stream
, "%s", rname
);
1082 if (operand
->flags
& ARC_OPERAND_TRUNCATE
)
1084 rname
= arcExtMap_coreRegName (value
+ 1);
1086 rname
= regnames
[value
+ 1];
1087 (*info
->fprintf_func
) (info
->stream
, "%s", rname
);
1090 else if (operand
->flags
& ARC_OPERAND_LIMM
)
1092 const char *rname
= get_auxreg (opcode
, value
, isa_mask
);
1094 if (rname
&& open_braket
)
1095 (*info
->fprintf_func
) (info
->stream
, "%s", rname
);
1098 (*info
->fprintf_func
) (info
->stream
, "%#x", value
);
1099 if (info
->insn_type
== dis_branch
1100 || info
->insn_type
== dis_jsr
)
1101 info
->target
= (bfd_vma
) value
;
1104 else if (operand
->flags
& ARC_OPERAND_PCREL
)
1107 if (info
->flags
& INSN_HAS_RELOC
)
1109 (*info
->print_address_func
) ((memaddr
& ~3) + value
, info
);
1111 info
->target
= (bfd_vma
) (memaddr
& ~3) + value
;
1113 else if (operand
->flags
& ARC_OPERAND_SIGNED
)
1115 const char *rname
= get_auxreg (opcode
, value
, isa_mask
);
1116 if (rname
&& open_braket
)
1117 (*info
->fprintf_func
) (info
->stream
, "%s", rname
);
1119 (*info
->fprintf_func
) (info
->stream
, "%d", value
);
1121 else if (operand
->flags
& ARC_OPERAND_ADDRTYPE
)
1123 const char *addrtype
= get_addrtype (value
);
1124 (*info
->fprintf_func
) (info
->stream
, "%s", addrtype
);
1125 /* A colon follow an address type. */
1130 if (operand
->flags
& ARC_OPERAND_TRUNCATE
1131 && !(operand
->flags
& ARC_OPERAND_ALIGNED32
)
1132 && !(operand
->flags
& ARC_OPERAND_ALIGNED16
)
1133 && value
> 0 && value
<= 14)
1134 (*info
->fprintf_func
) (info
->stream
, "r13-%s",
1135 regnames
[13 + value
- 1]);
1138 const char *rname
= get_auxreg (opcode
, value
, isa_mask
);
1139 if (rname
&& open_braket
)
1140 (*info
->fprintf_func
) (info
->stream
, "%s", rname
);
1142 (*info
->fprintf_func
) (info
->stream
, "%#x", value
);
1152 arc_get_disassembler (bfd
*abfd
)
1154 /* BFD my be absent, if opcodes is invoked from the debugger that
1155 has connected to remote target and doesn't have an ELF file. */
1158 /* Read the extension insns and registers, if any. */
1159 build_ARC_extmap (abfd
);
1165 return print_insn_arc
;
1168 /* Disassemble ARC instructions. Used by debugger. */
1171 arcAnalyzeInstr (bfd_vma memaddr
,
1172 struct disassemble_info
*info
)
1174 struct arcDisState ret
;
1175 memset (&ret
, 0, sizeof (struct arcDisState
));
1177 ret
.instructionLen
= print_insn_arc (memaddr
, info
);
1180 ret
.words
[0] = insn
[0];
1181 ret
.words
[1] = insn
[1];
1183 ret
.coreRegName
= _coreRegName
;
1184 ret
.auxRegName
= _auxRegName
;
1185 ret
.condCodeName
= _condCodeName
;
1186 ret
.instName
= _instName
;
1193 print_arc_disassembler_options (FILE *stream
)
1195 fprintf (stream
, _("\n\
1196 The following ARC specific disassembler options are supported for use \n\
1197 with -M switch (multiple options should be separated by commas):\n"));
1199 fprintf (stream
, _("\
1200 dsp Recognize DSP instructions.\n"));
1201 fprintf (stream
, _("\
1202 spfp Recognize FPX SP instructions.\n"));
1203 fprintf (stream
, _("\
1204 dpfp Recognize FPX DP instructions.\n"));
1205 fprintf (stream
, _("\
1206 quarkse_em Recognize FPU QuarkSE-EM instructions.\n"));
1207 fprintf (stream
, _("\
1208 fpuda Recognize double assist FPU instructions.\n"));
1209 fprintf (stream
, _("\
1210 fpus Recognize single precision FPU instructions.\n"));
1211 fprintf (stream
, _("\
1212 fpud Recognize double precision FPU instructions.\n"));
1217 eval: (c-set-style "gnu")