1 /* Instruction printing code for the ARC.
2 Copyright (C) 1994-2017 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 /* A private data used by ARC decoder. */
55 struct arc_disassemble_info
57 /* The current disassembled arc opcode. */
58 const struct arc_opcode
*opcode
;
60 /* Instruction length w/o limm field. */
63 /* TRUE if we have limm. */
66 /* LIMM value, if exists. */
69 /* Condition code, if exists. */
70 unsigned condition_code
;
73 unsigned writeback_mode
;
75 /* Number of operands. */
76 unsigned operands_count
;
78 struct arc_insn_operand operands
[MAX_INSN_ARGS
];
81 /* Globals variables. */
83 static const char * const regnames
[64] =
85 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
86 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
87 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
88 "r24", "r25", "gp", "fp", "sp", "ilink", "r30", "blink",
90 "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
91 "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
92 "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",
93 "r56", "r57", "ACCL", "ACCH", "lp_count", "rezerved", "LIMM", "pcl"
96 static const char * const addrtypenames
[ARC_NUM_ADDRTYPES
] =
98 "bd", "jid", "lbd", "mbd", "sd", "sm", "xa", "xd",
99 "cd", "cbd", "cjid", "clbd", "cm", "csd", "cxa", "cxd"
102 static int addrtypenames_max
= ARC_NUM_ADDRTYPES
- 1;
104 static const char * const addrtypeunknown
= "unknown";
106 /* This structure keeps track which instruction class(es)
107 should be ignored durring disassembling. */
109 typedef struct skipclass
111 insn_class_t insn_class
;
112 insn_subclass_t subclass
;
113 struct skipclass
*nxt
;
114 } skipclass_t
, *linkclass
;
116 /* Intial classes of instructions to be consider first when
118 static linkclass decodelist
= NULL
;
120 /* ISA mask value enforced via disassembler info options. ARC_OPCODE_NONE
121 value means that no CPU is enforced. */
123 static unsigned enforced_isa_mask
= ARC_OPCODE_NONE
;
125 /* Macros section. */
128 # define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args)
130 # define pr_debug(fmt, args...)
133 #define ARRANGE_ENDIAN(info, buf) \
134 (info->endian == BFD_ENDIAN_LITTLE ? bfd_getm32 (bfd_getl32 (buf)) \
137 #define BITS(word,s,e) (((word) << (sizeof (word) * 8 - 1 - e)) >> \
138 (s + (sizeof (word) * 8 - 1 - e)))
139 #define OPCODE_32BIT_INSN(word) (BITS ((word), 27, 31))
141 /* Functions implementation. */
143 /* Initialize private data. */
145 init_arc_disasm_info (struct disassemble_info
*info
)
147 struct arc_disassemble_info
*arc_infop
148 = calloc (sizeof (*arc_infop
), 1);
150 if (arc_infop
== NULL
)
153 info
->private_data
= arc_infop
;
157 /* Add a new element to the decode list. */
160 add_to_decodelist (insn_class_t insn_class
,
161 insn_subclass_t subclass
)
163 linkclass t
= (linkclass
) xmalloc (sizeof (skipclass_t
));
165 t
->insn_class
= insn_class
;
166 t
->subclass
= subclass
;
171 /* Return TRUE if we need to skip the opcode from being
175 skip_this_opcode (const struct arc_opcode
*opcode
)
177 linkclass t
= decodelist
;
179 /* Check opcode for major 0x06, return if it is not in. */
180 if (arc_opcode_len (opcode
) == 4
181 && OPCODE_32BIT_INSN (opcode
->opcode
) != 0x06)
184 /* or not a known truble class. */
185 switch (opcode
->insn_class
)
197 if ((t
->insn_class
== opcode
->insn_class
)
198 && (t
->subclass
== opcode
->subclass
))
207 bfd_getm32 (unsigned int data
)
211 value
= ((data
& 0xff00) | (data
& 0xff)) << 16;
212 value
|= ((data
& 0xff0000) | (data
& 0xff000000)) >> 16;
217 special_flag_p (const char *opname
,
220 const struct arc_flag_special
*flg_spec
;
221 unsigned i
, j
, flgidx
;
223 for (i
= 0; i
< arc_num_flag_special
; i
++)
225 flg_spec
= &arc_flag_special_cases
[i
];
227 if (strcmp (opname
, flg_spec
->name
))
230 /* Found potential special case instruction. */
233 flgidx
= flg_spec
->flags
[j
];
235 break; /* End of the array. */
237 if (strcmp (flgname
, arc_flag_operands
[flgidx
].name
) == 0)
244 /* Find opcode from ARC_TABLE given the instruction described by INSN and
245 INSNLEN. The ISA_MASK restricts the possible matches in ARC_TABLE. */
247 static const struct arc_opcode
*
248 find_format_from_table (struct disassemble_info
*info
,
249 const struct arc_opcode
*arc_table
,
250 unsigned long long insn
,
251 unsigned int insn_len
,
253 bfd_boolean
*has_limm
,
254 bfd_boolean overlaps
)
257 const struct arc_opcode
*opcode
= NULL
;
258 const struct arc_opcode
*t_op
= NULL
;
259 const unsigned char *opidx
;
260 const unsigned char *flgidx
;
261 bfd_boolean warn_p
= FALSE
;
265 bfd_boolean invalid
= FALSE
;
267 opcode
= &arc_table
[i
++];
269 if (!(opcode
->cpu
& isa_mask
))
272 if (arc_opcode_len (opcode
) != (int) insn_len
)
275 if ((insn
& opcode
->mask
) != opcode
->opcode
)
280 /* Possible candidate, check the operands. */
281 for (opidx
= opcode
->operands
; *opidx
; opidx
++)
284 const struct arc_operand
*operand
= &arc_operands
[*opidx
];
286 if (operand
->flags
& ARC_OPERAND_FAKE
)
289 if (operand
->extract
)
290 value
= (*operand
->extract
) (insn
, &invalid
);
292 value
= (insn
>> operand
->shift
) & ((1 << operand
->bits
) - 1);
294 /* Check for LIMM indicator. If it is there, then make sure
295 we pick the right format. */
296 limmind
= (isa_mask
& ARC_OPCODE_ARCV2
) ? 0x1E : 0x3E;
297 if (operand
->flags
& ARC_OPERAND_IR
298 && !(operand
->flags
& ARC_OPERAND_LIMM
))
300 if ((value
== 0x3E && insn_len
== 4)
301 || (value
== limmind
&& insn_len
== 2))
308 if (operand
->flags
& ARC_OPERAND_LIMM
309 && !(operand
->flags
& ARC_OPERAND_DUPLICATE
))
313 /* Check the flags. */
314 for (flgidx
= opcode
->flags
; *flgidx
; flgidx
++)
316 /* Get a valid flag class. */
317 const struct arc_flag_class
*cl_flags
= &arc_flag_classes
[*flgidx
];
318 const unsigned *flgopridx
;
319 int foundA
= 0, foundB
= 0;
322 /* Check first the extensions. */
323 if (cl_flags
->flag_class
& F_CLASS_EXTEND
)
325 value
= (insn
& 0x1F);
326 if (arcExtMap_condCodeName (value
))
330 /* Check for the implicit flags. */
331 if (cl_flags
->flag_class
& F_CLASS_IMPLICIT
)
334 for (flgopridx
= cl_flags
->flags
; *flgopridx
; ++flgopridx
)
336 const struct arc_flag_operand
*flg_operand
=
337 &arc_flag_operands
[*flgopridx
];
339 value
= (insn
>> flg_operand
->shift
)
340 & ((1 << flg_operand
->bits
) - 1);
341 if (value
== flg_operand
->code
)
347 if (!foundA
&& foundB
)
362 if (skip_this_opcode (opcode
))
366 /* The instruction is valid. */
369 while (opcode
->mask
);
373 info
->fprintf_func (info
->stream
,
374 _("\nWarning: disassembly may be wrong due to "
375 "guessed opcode class choice.\n"
376 "Use -M<class[,class]> to select the correct "
377 "opcode class(es).\n\t\t\t\t"));
384 /* Find opcode for INSN, trying various different sources. The instruction
385 length in INSN_LEN will be updated if the instruction requires a LIMM
388 A pointer to the opcode is placed into OPCODE_RESULT, and ITER is
389 initialised, ready to iterate over the operands of the found opcode. If
390 the found opcode requires a LIMM then the LIMM value will be loaded into a
393 This function returns TRUE in almost all cases, FALSE is reserved to
394 indicate an error (failing to find an opcode is not an error) a returned
395 result of FALSE would indicate that the disassembler can't continue.
397 If no matching opcode is found then the returned result will be TRUE, the
398 value placed into OPCODE_RESULT will be NULL, ITER will be undefined, and
399 INSN_LEN will be unchanged.
401 If a matching opcode is found, then the returned result will be TRUE, the
402 opcode pointer is placed into OPCODE_RESULT, INSN_LEN will be increased by
403 4 if the instruction requires a LIMM, and the LIMM value will have been
404 loaded into a field of ITER. Finally, ITER will have been initialised so
405 that calls to OPERAND_ITERATOR_NEXT will iterate over the opcode's
409 find_format (bfd_vma memaddr
,
410 unsigned long long insn
,
411 unsigned int * insn_len
,
413 struct disassemble_info
* info
,
414 const struct arc_opcode
** opcode_result
,
415 struct arc_operand_iterator
* iter
)
417 const struct arc_opcode
*opcode
= NULL
;
418 bfd_boolean needs_limm
;
419 const extInstruction_t
*einsn
, *i
;
421 struct arc_disassemble_info
*arc_infop
= info
->private_data
;
423 /* First, try the extension instructions. */
426 einsn
= arcExtMap_insn (OPCODE_32BIT_INSN (insn
), insn
);
427 for (i
= einsn
; (i
!= NULL
) && (opcode
== NULL
); i
= i
->next
)
429 const char *errmsg
= NULL
;
431 opcode
= arcExtMap_genOpcode (i
, isa_mask
, &errmsg
);
434 (*info
->fprintf_func
) (info
->stream
, "\
435 An error occured while generating the extension instruction operations");
436 *opcode_result
= NULL
;
440 opcode
= find_format_from_table (info
, opcode
, insn
, *insn_len
,
441 isa_mask
, &needs_limm
, FALSE
);
445 /* Then, try finding the first match in the opcode table. */
447 opcode
= find_format_from_table (info
, arc_opcodes
, insn
, *insn_len
,
448 isa_mask
, &needs_limm
, TRUE
);
450 if (needs_limm
&& opcode
!= NULL
)
455 status
= (*info
->read_memory_func
) (memaddr
+ *insn_len
, buffer
,
463 limm
= ARRANGE_ENDIAN (info
, buffer
);
472 iter
->opcode
= opcode
;
473 iter
->opidx
= opcode
->operands
;
476 *opcode_result
= opcode
;
478 /* Update private data. */
479 arc_infop
->opcode
= opcode
;
480 arc_infop
->limm
= (needs_limm
) ? limm
: 0;
481 arc_infop
->limm_p
= needs_limm
;
487 print_flags (const struct arc_opcode
*opcode
,
488 unsigned long long *insn
,
489 struct disassemble_info
*info
)
491 const unsigned char *flgidx
;
493 struct arc_disassemble_info
*arc_infop
= info
->private_data
;
495 /* Now extract and print the flags. */
496 for (flgidx
= opcode
->flags
; *flgidx
; flgidx
++)
498 /* Get a valid flag class. */
499 const struct arc_flag_class
*cl_flags
= &arc_flag_classes
[*flgidx
];
500 const unsigned *flgopridx
;
502 /* Check first the extensions. */
503 if (cl_flags
->flag_class
& F_CLASS_EXTEND
)
506 value
= (insn
[0] & 0x1F);
508 name
= arcExtMap_condCodeName (value
);
511 (*info
->fprintf_func
) (info
->stream
, ".%s", name
);
516 for (flgopridx
= cl_flags
->flags
; *flgopridx
; ++flgopridx
)
518 const struct arc_flag_operand
*flg_operand
=
519 &arc_flag_operands
[*flgopridx
];
521 /* Implicit flags are only used for the insn decoder. */
522 if (cl_flags
->flag_class
& F_CLASS_IMPLICIT
)
524 if (cl_flags
->flag_class
& F_CLASS_COND
)
525 arc_infop
->condition_code
= flg_operand
->code
;
526 else if (cl_flags
->flag_class
& F_CLASS_WB
)
527 arc_infop
->writeback_mode
= flg_operand
->code
;
528 else if (cl_flags
->flag_class
& F_CLASS_ZZ
)
529 info
->data_size
= flg_operand
->code
;
533 if (!flg_operand
->favail
)
536 value
= (insn
[0] >> flg_operand
->shift
)
537 & ((1 << flg_operand
->bits
) - 1);
538 if (value
== flg_operand
->code
)
540 /* FIXME!: print correctly nt/t flag. */
541 if (!special_flag_p (opcode
->name
, flg_operand
->name
))
542 (*info
->fprintf_func
) (info
->stream
, ".");
543 else if (info
->insn_type
== dis_dref
)
545 switch (flg_operand
->name
[0])
559 if (flg_operand
->name
[0] == 'd'
560 && flg_operand
->name
[1] == 0)
561 info
->branch_delay_insns
= 1;
563 /* Check if it is a conditional flag. */
564 if (cl_flags
->flag_class
& F_CLASS_COND
)
566 if (info
->insn_type
== dis_jsr
)
567 info
->insn_type
= dis_condjsr
;
568 else if (info
->insn_type
== dis_branch
)
569 info
->insn_type
= dis_condbranch
;
570 arc_infop
->condition_code
= flg_operand
->code
;
573 /* Check for the write back modes. */
574 if (cl_flags
->flag_class
& F_CLASS_WB
)
575 arc_infop
->writeback_mode
= flg_operand
->code
;
577 (*info
->fprintf_func
) (info
->stream
, "%s", flg_operand
->name
);
584 get_auxreg (const struct arc_opcode
*opcode
,
590 const struct arc_aux_reg
*auxr
= &arc_aux_regs
[0];
592 if (opcode
->insn_class
!= AUXREG
)
595 name
= arcExtMap_auxRegName (value
);
599 for (i
= 0; i
< arc_num_aux_regs
; i
++, auxr
++)
601 if (!(auxr
->cpu
& isa_mask
))
604 if (auxr
->subclass
!= NONE
)
607 if (auxr
->address
== value
)
613 /* Convert a value representing an address type to a string used to refer to
614 the address type in assembly code. */
617 get_addrtype (int value
)
619 if (value
< 0 || value
> addrtypenames_max
)
620 return addrtypeunknown
;
622 return addrtypenames
[value
];
625 /* Calculate the instruction length for an instruction starting with MSB
626 and LSB, the most and least significant byte. The ISA_MASK is used to
627 filter the instructions considered to only those that are part of the
628 current architecture.
630 The instruction lengths are calculated from the ARC_OPCODE table, and
631 cached for later use. */
634 arc_insn_length (bfd_byte msb
, bfd_byte lsb
, struct disassemble_info
*info
)
636 bfd_byte major_opcode
= msb
>> 3;
640 case bfd_mach_arc_arc700
:
641 /* The nps400 extension set requires this special casing of the
642 instruction length calculation. Right now this is not causing any
643 problems as none of the known extensions overlap in opcode space,
644 but, if they ever do then we might need to start carrying
645 information around in the elf about which extensions are in use. */
646 if (major_opcode
== 0xb)
648 bfd_byte minor_opcode
= lsb
& 0x1f;
650 if (minor_opcode
< 4)
652 else if (minor_opcode
== 0x10 || minor_opcode
== 0x11)
655 if (major_opcode
== 0xa)
660 case bfd_mach_arc_arc600
:
661 return (major_opcode
> 0xb) ? 2 : 4;
664 case bfd_mach_arc_arcv2
:
665 return (major_opcode
> 0x7) ? 2 : 4;
673 /* Extract and return the value of OPERAND from the instruction whose value
674 is held in the array INSN. */
677 extract_operand_value (const struct arc_operand
*operand
,
678 unsigned long long insn
,
683 /* Read the limm operand, if required. */
684 if (operand
->flags
& ARC_OPERAND_LIMM
)
685 /* The second part of the instruction value will have been loaded as
686 part of the find_format call made earlier. */
690 if (operand
->extract
)
691 value
= (*operand
->extract
) (insn
, (int *) NULL
);
694 if (operand
->flags
& ARC_OPERAND_ALIGNED32
)
696 value
= (insn
>> operand
->shift
)
697 & ((1 << (operand
->bits
- 2)) - 1);
702 value
= (insn
>> operand
->shift
) & ((1 << operand
->bits
) - 1);
704 if (operand
->flags
& ARC_OPERAND_SIGNED
)
706 int signbit
= 1 << (operand
->bits
- 1);
707 value
= (value
^ signbit
) - signbit
;
715 /* Find the next operand, and the operands value from ITER. Return TRUE if
716 there is another operand, otherwise return FALSE. If there is an
717 operand returned then the operand is placed into OPERAND, and the value
718 into VALUE. If there is no operand returned then OPERAND and VALUE are
722 operand_iterator_next (struct arc_operand_iterator
*iter
,
723 const struct arc_operand
**operand
,
726 if (*iter
->opidx
== 0)
732 *operand
= &arc_operands
[*iter
->opidx
];
733 *value
= extract_operand_value (*operand
, iter
->insn
, iter
->limm
);
739 /* Helper for parsing the options. */
742 parse_option (const char *option
)
744 if (disassembler_options_cmp (option
, "dsp") == 0)
745 add_to_decodelist (DSP
, NONE
);
747 else if (disassembler_options_cmp (option
, "spfp") == 0)
748 add_to_decodelist (FLOAT
, SPX
);
750 else if (disassembler_options_cmp (option
, "dpfp") == 0)
751 add_to_decodelist (FLOAT
, DPX
);
753 else if (disassembler_options_cmp (option
, "quarkse_em") == 0)
755 add_to_decodelist (FLOAT
, DPX
);
756 add_to_decodelist (FLOAT
, SPX
);
757 add_to_decodelist (FLOAT
, QUARKSE1
);
758 add_to_decodelist (FLOAT
, QUARKSE2
);
761 else if (disassembler_options_cmp (option
, "fpuda") == 0)
762 add_to_decodelist (FLOAT
, DPA
);
764 else if (disassembler_options_cmp (option
, "fpus") == 0)
766 add_to_decodelist (FLOAT
, SP
);
767 add_to_decodelist (FLOAT
, CVT
);
770 else if (disassembler_options_cmp (option
, "fpud") == 0)
772 add_to_decodelist (FLOAT
, DP
);
773 add_to_decodelist (FLOAT
, CVT
);
776 fprintf (stderr
, _("Unrecognised disassembler option: %s\n"), option
);
779 #define ARC_CPU_TYPE_A6xx(NAME,EXTRA) \
780 { #NAME, ARC_OPCODE_ARC600, "ARC600" }
781 #define ARC_CPU_TYPE_A7xx(NAME,EXTRA) \
782 { #NAME, ARC_OPCODE_ARC700, "ARC700" }
783 #define ARC_CPU_TYPE_AV2EM(NAME,EXTRA) \
784 { #NAME, ARC_OPCODE_ARCv2EM, "ARC EM" }
785 #define ARC_CPU_TYPE_AV2HS(NAME,EXTRA) \
786 { #NAME, ARC_OPCODE_ARCv2HS, "ARC HS" }
787 #define ARC_CPU_TYPE_NONE \
790 /* A table of CPU names and opcode sets. */
791 static const struct cpu_type
799 #include "elf/arc-cpu.def"
802 /* Helper for parsing the CPU options. Accept any of the ARC architectures
803 values. OPTION should be a value passed to cpu=. */
806 parse_cpu_option (const char *option
)
810 for (i
= 0; cpu_types
[i
].name
; ++i
)
812 if (!disassembler_options_cmp (cpu_types
[i
].name
, option
))
814 return cpu_types
[i
].flags
;
818 fprintf (stderr
, _("Unrecognised disassembler CPU option: %s\n"), option
);
819 return ARC_OPCODE_NONE
;
822 /* Go over the options list and parse it. */
825 parse_disassembler_options (const char *options
)
832 /* Disassembler might be reused for difference CPU's, and cpu option set for
833 the first one shouldn't be applied to second (which might not have
834 explicit cpu in its options. Therefore it is required to reset enforced
835 CPU when new options are being parsed. */
836 enforced_isa_mask
= ARC_OPCODE_NONE
;
838 FOR_EACH_DISASSEMBLER_OPTION (option
, options
)
840 /* A CPU option? Cannot use STRING_COMMA_LEN because strncmp is also a
841 preprocessor macro. */
842 if (strncmp (option
, "cpu=", 4) == 0)
843 /* Strip leading `cpu=`. */
844 enforced_isa_mask
= parse_cpu_option (option
+ 4);
846 parse_option (option
);
850 /* Return the instruction type for an instruction described by OPCODE. */
852 static enum dis_insn_type
853 arc_opcode_to_insn_type (const struct arc_opcode
*opcode
)
855 enum dis_insn_type insn_type
;
857 switch (opcode
->insn_class
)
869 if (!strncmp (opcode
->name
, "bl", 2)
870 || !strncmp (opcode
->name
, "jl", 2))
872 if (opcode
->subclass
== COND
)
873 insn_type
= dis_condjsr
;
879 if (opcode
->subclass
== COND
)
880 insn_type
= dis_condbranch
;
882 insn_type
= dis_branch
;
891 insn_type
= dis_dref
;
894 insn_type
= dis_branch
;
897 insn_type
= dis_nonbranch
;
904 /* Disassemble ARC instructions. */
907 print_insn_arc (bfd_vma memaddr
,
908 struct disassemble_info
*info
)
911 unsigned int highbyte
, lowbyte
;
913 unsigned int insn_len
;
914 unsigned long long insn
= 0;
915 unsigned isa_mask
= ARC_OPCODE_NONE
;
916 const struct arc_opcode
*opcode
;
917 bfd_boolean need_comma
;
918 bfd_boolean open_braket
;
920 const struct arc_operand
*operand
;
922 struct arc_operand_iterator iter
;
923 struct arc_disassemble_info
*arc_infop
;
925 if (info
->disassembler_options
)
927 parse_disassembler_options (info
->disassembler_options
);
929 /* Avoid repeated parsing of the options. */
930 info
->disassembler_options
= NULL
;
933 if (info
->private_data
== NULL
&& !init_arc_disasm_info (info
))
936 memset (&iter
, 0, sizeof (iter
));
937 highbyte
= ((info
->endian
== BFD_ENDIAN_LITTLE
) ? 1 : 0);
938 lowbyte
= ((info
->endian
== BFD_ENDIAN_LITTLE
) ? 0 : 1);
940 /* Figure out CPU type, unless it was enforced via disassembler options. */
941 if (enforced_isa_mask
== ARC_OPCODE_NONE
)
943 Elf_Internal_Ehdr
*header
= NULL
;
945 if (info
->section
&& info
->section
->owner
)
946 header
= elf_elfheader (info
->section
->owner
);
950 case bfd_mach_arc_arc700
:
951 isa_mask
= ARC_OPCODE_ARC700
;
954 case bfd_mach_arc_arc600
:
955 isa_mask
= ARC_OPCODE_ARC600
;
958 case bfd_mach_arc_arcv2
:
960 isa_mask
= ARC_OPCODE_ARCv2EM
;
961 /* TODO: Perhaps remove definition of header since it is only used at
964 && (header
->e_flags
& EF_ARC_MACH_MSK
) == EF_ARC_CPU_ARCV2HS
)
965 isa_mask
= ARC_OPCODE_ARCv2HS
;
970 isa_mask
= enforced_isa_mask
;
972 if (isa_mask
== ARC_OPCODE_ARCv2HS
)
974 /* FPU instructions are not extensions for HS. */
975 add_to_decodelist (FLOAT
, SP
);
976 add_to_decodelist (FLOAT
, DP
);
977 add_to_decodelist (FLOAT
, CVT
);
980 /* This variable may be set by the instruction decoder. It suggests
981 the number of bytes objdump should display on a single line. If
982 the instruction decoder sets this, it should always set it to
983 the same value in order to get reasonable looking output. */
985 info
->bytes_per_line
= 8;
987 /* In the next lines, we set two info variables control the way
988 objdump displays the raw data. For example, if bytes_per_line is
989 8 and bytes_per_chunk is 4, the output will look like this:
990 00: 00000000 00000000
991 with the chunks displayed according to "display_endian". */
994 && !(info
->section
->flags
& SEC_CODE
))
996 /* This is not a CODE section. */
997 switch (info
->section
->size
)
1002 size
= info
->section
->size
;
1005 size
= (info
->section
->size
& 0x01) ? 1 : 4;
1008 info
->bytes_per_chunk
= 1;
1009 info
->display_endian
= info
->endian
;
1014 info
->bytes_per_chunk
= 2;
1015 info
->display_endian
= info
->endian
;
1018 /* Read the insn into a host word. */
1019 status
= (*info
->read_memory_func
) (memaddr
, buffer
, size
, info
);
1022 (*info
->memory_error_func
) (status
, memaddr
, info
);
1027 && !(info
->section
->flags
& SEC_CODE
))
1032 data
= bfd_get_bits (buffer
, size
* 8,
1033 info
->display_endian
== BFD_ENDIAN_BIG
);
1037 (*info
->fprintf_func
) (info
->stream
, ".byte\t0x%02lx", data
);
1040 (*info
->fprintf_func
) (info
->stream
, ".short\t0x%04lx", data
);
1043 (*info
->fprintf_func
) (info
->stream
, ".word\t0x%08lx", data
);
1051 insn_len
= arc_insn_length (buffer
[highbyte
], buffer
[lowbyte
], info
);
1052 pr_debug ("instruction length = %d bytes\n", insn_len
);
1053 arc_infop
= info
->private_data
;
1054 arc_infop
->insn_len
= insn_len
;
1059 insn
= (buffer
[highbyte
] << 8) | buffer
[lowbyte
];
1064 /* This is a long instruction: Read the remaning 2 bytes. */
1065 status
= (*info
->read_memory_func
) (memaddr
+ 2, &buffer
[2], 2, info
);
1068 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
1071 insn
= (unsigned long long) ARRANGE_ENDIAN (info
, buffer
);
1077 status
= (*info
->read_memory_func
) (memaddr
+ 2, &buffer
[2], 4, info
);
1080 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
1083 insn
= (unsigned long long) ARRANGE_ENDIAN (info
, &buffer
[2]);
1084 insn
|= ((unsigned long long) buffer
[highbyte
] << 40)
1085 | ((unsigned long long) buffer
[lowbyte
] << 32);
1091 status
= (*info
->read_memory_func
) (memaddr
+ 2, &buffer
[2], 6, info
);
1094 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
1098 ((((unsigned long long) ARRANGE_ENDIAN (info
, buffer
)) << 32)
1099 | ((unsigned long long) ARRANGE_ENDIAN (info
, &buffer
[4])));
1104 /* There is no instruction whose length is not 2, 4, 6, or 8. */
1108 pr_debug ("instruction value = %llx\n", insn
);
1110 /* Set some defaults for the insn info. */
1111 info
->insn_info_valid
= 1;
1112 info
->branch_delay_insns
= 0;
1113 info
->data_size
= 4;
1114 info
->insn_type
= dis_nonbranch
;
1118 /* FIXME to be moved in dissasemble_init_for_target. */
1119 info
->disassembler_needs_relocs
= TRUE
;
1121 /* Find the first match in the opcode table. */
1122 if (!find_format (memaddr
, insn
, &insn_len
, isa_mask
, info
, &opcode
, &iter
))
1130 (*info
->fprintf_func
) (info
->stream
, ".long %#04llx",
1134 (*info
->fprintf_func
) (info
->stream
, ".long %#08llx",
1138 (*info
->fprintf_func
) (info
->stream
, ".long %#08llx",
1140 (*info
->fprintf_func
) (info
->stream
, ".long %#04llx",
1141 (insn
>> 32) & 0xffff);
1144 (*info
->fprintf_func
) (info
->stream
, ".long %#08llx",
1146 (*info
->fprintf_func
) (info
->stream
, ".long %#08llx",
1153 info
->insn_type
= dis_noninsn
;
1157 /* Print the mnemonic. */
1158 (*info
->fprintf_func
) (info
->stream
, "%s", opcode
->name
);
1160 /* Preselect the insn class. */
1161 info
->insn_type
= arc_opcode_to_insn_type (opcode
);
1163 pr_debug ("%s: 0x%08llx\n", opcode
->name
, opcode
->opcode
);
1165 print_flags (opcode
, &insn
, info
);
1167 if (opcode
->operands
[0] != 0)
1168 (*info
->fprintf_func
) (info
->stream
, "\t");
1171 open_braket
= FALSE
;
1172 arc_infop
->operands_count
= 0;
1174 /* Now extract and print the operands. */
1176 while (operand_iterator_next (&iter
, &operand
, &value
))
1178 if (open_braket
&& (operand
->flags
& ARC_OPERAND_BRAKET
))
1180 (*info
->fprintf_func
) (info
->stream
, "]");
1181 open_braket
= FALSE
;
1185 /* Only take input from real operands. */
1186 if (ARC_OPERAND_IS_FAKE (operand
))
1189 if ((operand
->flags
& ARC_OPERAND_IGNORE
)
1190 && (operand
->flags
& ARC_OPERAND_IR
)
1194 if (operand
->flags
& ARC_OPERAND_COLON
)
1196 (*info
->fprintf_func
) (info
->stream
, ":");
1201 (*info
->fprintf_func
) (info
->stream
, ",");
1203 if (!open_braket
&& (operand
->flags
& ARC_OPERAND_BRAKET
))
1205 (*info
->fprintf_func
) (info
->stream
, "[");
1213 /* Print the operand as directed by the flags. */
1214 if (operand
->flags
& ARC_OPERAND_IR
)
1218 assert (value
>=0 && value
< 64);
1219 rname
= arcExtMap_coreRegName (value
);
1221 rname
= regnames
[value
];
1222 (*info
->fprintf_func
) (info
->stream
, "%s", rname
);
1223 if (operand
->flags
& ARC_OPERAND_TRUNCATE
)
1225 rname
= arcExtMap_coreRegName (value
+ 1);
1227 rname
= regnames
[value
+ 1];
1228 (*info
->fprintf_func
) (info
->stream
, "%s", rname
);
1231 else if (operand
->flags
& ARC_OPERAND_LIMM
)
1233 const char *rname
= get_auxreg (opcode
, value
, isa_mask
);
1235 if (rname
&& open_braket
)
1236 (*info
->fprintf_func
) (info
->stream
, "%s", rname
);
1239 (*info
->fprintf_func
) (info
->stream
, "%#x", value
);
1240 if (info
->insn_type
== dis_branch
1241 || info
->insn_type
== dis_jsr
)
1242 info
->target
= (bfd_vma
) value
;
1245 else if (operand
->flags
& ARC_OPERAND_PCREL
)
1248 if (info
->flags
& INSN_HAS_RELOC
)
1250 (*info
->print_address_func
) ((memaddr
& ~3) + value
, info
);
1252 info
->target
= (bfd_vma
) (memaddr
& ~3) + value
;
1254 else if (operand
->flags
& ARC_OPERAND_SIGNED
)
1256 const char *rname
= get_auxreg (opcode
, value
, isa_mask
);
1257 if (rname
&& open_braket
)
1258 (*info
->fprintf_func
) (info
->stream
, "%s", rname
);
1260 (*info
->fprintf_func
) (info
->stream
, "%d", value
);
1262 else if (operand
->flags
& ARC_OPERAND_ADDRTYPE
)
1264 const char *addrtype
= get_addrtype (value
);
1265 (*info
->fprintf_func
) (info
->stream
, "%s", addrtype
);
1266 /* A colon follow an address type. */
1271 if (operand
->flags
& ARC_OPERAND_TRUNCATE
1272 && !(operand
->flags
& ARC_OPERAND_ALIGNED32
)
1273 && !(operand
->flags
& ARC_OPERAND_ALIGNED16
)
1274 && value
>= 0 && value
<= 14)
1282 (*info
->fprintf_func
) (info
->stream
, "r13");
1285 (*info
->fprintf_func
) (info
->stream
, "r13-%s",
1286 regnames
[13 + value
- 1]);
1292 const char *rname
= get_auxreg (opcode
, value
, isa_mask
);
1293 if (rname
&& open_braket
)
1294 (*info
->fprintf_func
) (info
->stream
, "%s", rname
);
1296 (*info
->fprintf_func
) (info
->stream
, "%#x", value
);
1300 if (operand
->flags
& ARC_OPERAND_LIMM
)
1302 arc_infop
->operands
[arc_infop
->operands_count
].kind
1303 = ARC_OPERAND_KIND_LIMM
;
1304 /* It is not important to have exactly the LIMM indicator
1306 arc_infop
->operands
[arc_infop
->operands_count
].value
= 63;
1310 arc_infop
->operands
[arc_infop
->operands_count
].value
= value
;
1311 arc_infop
->operands
[arc_infop
->operands_count
].kind
1312 = (operand
->flags
& ARC_OPERAND_IR
1313 ? ARC_OPERAND_KIND_REG
1314 : ARC_OPERAND_KIND_SHIMM
);
1316 arc_infop
->operands_count
++;
1324 arc_get_disassembler (bfd
*abfd
)
1326 /* BFD my be absent, if opcodes is invoked from the debugger that
1327 has connected to remote target and doesn't have an ELF file. */
1330 /* Read the extension insns and registers, if any. */
1331 build_ARC_extmap (abfd
);
1337 return print_insn_arc
;
1341 print_arc_disassembler_options (FILE *stream
)
1345 fprintf (stream
, _("\n\
1346 The following ARC specific disassembler options are supported for use \n\
1347 with -M switch (multiple options should be separated by commas):\n"));
1349 /* cpu=... options. */
1350 for (i
= 0; cpu_types
[i
].name
; ++i
)
1352 /* As of now all value CPU values are less than 16 characters. */
1353 fprintf (stream
, " cpu=%-16s\tEnforce %s ISA.\n",
1354 cpu_types
[i
].name
, cpu_types
[i
].isa
);
1357 fprintf (stream
, _("\
1358 dsp Recognize DSP instructions.\n"));
1359 fprintf (stream
, _("\
1360 spfp Recognize FPX SP instructions.\n"));
1361 fprintf (stream
, _("\
1362 dpfp Recognize FPX DP instructions.\n"));
1363 fprintf (stream
, _("\
1364 quarkse_em Recognize FPU QuarkSE-EM instructions.\n"));
1365 fprintf (stream
, _("\
1366 fpuda Recognize double assist FPU instructions.\n"));
1367 fprintf (stream
, _("\
1368 fpus Recognize single precision FPU instructions.\n"));
1369 fprintf (stream
, _("\
1370 fpud Recognize double precision FPU instructions.\n"));
1373 void arc_insn_decode (bfd_vma addr
,
1374 struct disassemble_info
*info
,
1375 disassembler_ftype disasm_func
,
1376 struct arc_instruction
*insn
)
1378 const struct arc_opcode
*opcode
;
1379 struct arc_disassemble_info
*arc_infop
;
1381 /* Ensure that insn would be in the reset state. */
1382 memset (insn
, 0, sizeof (struct arc_instruction
));
1384 /* There was an error when disassembling, for example memory read error. */
1385 if (disasm_func (addr
, info
) < 0)
1387 insn
->valid
= FALSE
;
1391 assert (info
->private_data
!= NULL
);
1392 arc_infop
= info
->private_data
;
1394 insn
->length
= arc_infop
->insn_len
;;
1395 insn
->address
= addr
;
1397 /* Quick exit if memory at this address is not an instruction. */
1398 if (info
->insn_type
== dis_noninsn
)
1400 insn
->valid
= FALSE
;
1406 opcode
= (const struct arc_opcode
*) arc_infop
->opcode
;
1407 insn
->insn_class
= opcode
->insn_class
;
1408 insn
->limm_value
= arc_infop
->limm
;
1409 insn
->limm_p
= arc_infop
->limm_p
;
1411 insn
->is_control_flow
= (info
->insn_type
== dis_branch
1412 || info
->insn_type
== dis_condbranch
1413 || info
->insn_type
== dis_jsr
1414 || info
->insn_type
== dis_condjsr
);
1416 insn
->has_delay_slot
= info
->branch_delay_insns
;
1417 insn
->writeback_mode
1418 = (enum arc_ldst_writeback_mode
) arc_infop
->writeback_mode
;
1419 insn
->data_size_mode
= info
->data_size
;
1420 insn
->condition_code
= arc_infop
->condition_code
;
1421 memcpy (insn
->operands
, arc_infop
->operands
,
1422 sizeof (struct arc_insn_operand
) * MAX_INSN_ARGS
);
1423 insn
->operands_count
= arc_infop
->operands_count
;
1427 eval: (c-set-style "gnu")