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
42 OPERAND_ITERATOR_STANDARD
,
46 /* The array of 32-bit values that make up this instruction. All
47 required values have been pre-loaded into this array during the
55 /* The opcode this iterator is operating on. */
56 const struct arc_opcode
*opcode
;
58 /* The index into the opcodes operand index list. */
59 const unsigned char *opidx
;
64 /* The long instruction opcode this iterator is operating on. */
65 const struct arc_long_opcode
*long_opcode
;
67 /* Two indexes into the opcodes operand index lists. */
68 const unsigned char *opidx_base
, *opidx_limm
;
73 /* Globals variables. */
75 static const char * const regnames
[64] =
77 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
78 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
79 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
80 "r24", "r25", "gp", "fp", "sp", "ilink", "r30", "blink",
82 "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
83 "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
84 "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",
85 "r56", "r57", "ACCL", "ACCH", "lp_count", "rezerved", "LIMM", "pcl"
88 /* This structure keeps track which instruction class(es)
89 should be ignored durring disassembling. */
91 typedef struct skipclass
93 insn_class_t insn_class
;
94 insn_subclass_t subclass
;
95 struct skipclass
*nxt
;
96 } skipclass_t
, *linkclass
;
98 /* Intial classes of instructions to be consider first when
100 static linkclass decodelist
= NULL
;
102 /* Macros section. */
105 # define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args)
107 # define pr_debug(fmt, args...)
110 #define ARRANGE_ENDIAN(info, buf) \
111 (info->endian == BFD_ENDIAN_LITTLE ? bfd_getm32 (bfd_getl32 (buf)) \
114 #define BITS(word,s,e) (((word) << (sizeof (word) * 8 - 1 - e)) >> \
115 (s + (sizeof (word) * 8 - 1 - e)))
116 #define OPCODE(word) (BITS ((word), 27, 31))
118 #define OPCODE_AC(word) (BITS ((word), 11, 15))
120 /* Functions implementation. */
122 /* Return TRUE when two classes are not opcode conflicting. */
125 is_compatible_p (insn_class_t classA
,
126 insn_subclass_t sclassA
,
128 insn_subclass_t sclassB
)
130 if (classA
== DSP
&& sclassB
== DPX
)
132 if (sclassA
== DPX
&& classB
== DSP
)
137 /* Add a new element to the decode list. */
140 add_to_decodelist (insn_class_t insn_class
,
141 insn_subclass_t subclass
)
143 linkclass t
= (linkclass
) xmalloc (sizeof (skipclass_t
));
145 t
->insn_class
= insn_class
;
146 t
->subclass
= subclass
;
151 /* Return TRUE if we need to skip the opcode from being
155 skip_this_opcode (const struct arc_opcode
* opcode
,
156 struct disassemble_info
* info
)
158 linkclass t
= decodelist
;
159 bfd_boolean addme
= TRUE
;
161 /* Check opcode for major 0x06, return if it is not in. */
162 if (OPCODE (opcode
->opcode
) != 0x06)
166 && is_compatible_p (t
->insn_class
, t
->subclass
,
167 opcode
->insn_class
, opcode
->subclass
))
169 if ((t
->insn_class
== opcode
->insn_class
)
170 && (t
->subclass
== opcode
->subclass
))
175 /* If we found an incompatibility then we must skip. */
179 /* Even if we do not precisely know the if the right mnemonics
180 is correctly displayed, keep the disassmbled code class
184 switch (opcode
->insn_class
)
188 /* Add to the conflict list only the classes which
190 add_to_decodelist (opcode
->insn_class
, opcode
->subclass
);
191 /* Warn if we have to decode an opcode and no preferred
192 classes have been chosen. */
193 info
->fprintf_func (info
->stream
, _("\n\
194 Warning: disassembly may be wrong due to guessed opcode class choice.\n\
195 Use -M<class[,class]> to select the correct opcode class(es).\n\t\t\t\t"));
205 bfd_getm32 (unsigned int data
)
209 value
= ((data
& 0xff00) | (data
& 0xff)) << 16;
210 value
|= ((data
& 0xff0000) | (data
& 0xff000000)) >> 16;
215 special_flag_p (const char *opname
,
218 const struct arc_flag_special
*flg_spec
;
219 unsigned i
, j
, flgidx
;
221 for (i
= 0; i
< arc_num_flag_special
; i
++)
223 flg_spec
= &arc_flag_special_cases
[i
];
225 if (strcmp (opname
, flg_spec
->name
))
228 /* Found potential special case instruction. */
231 flgidx
= flg_spec
->flags
[j
];
233 break; /* End of the array. */
235 if (strcmp (flgname
, arc_flag_operands
[flgidx
].name
) == 0)
242 /* Find opcode from ARC_TABLE given the instruction described by INSN and
243 INSNLEN. The ISA_MASK restricts the possible matches in ARC_TABLE. */
245 static const struct arc_opcode
*
246 find_format_from_table (struct disassemble_info
*info
,
247 const struct arc_opcode
*arc_table
,
249 unsigned int insn_len
,
251 bfd_boolean
*has_limm
,
252 bfd_boolean overlaps
)
255 const struct arc_opcode
*opcode
= NULL
;
256 const unsigned char *opidx
;
257 const unsigned char *flgidx
;
261 bfd_boolean invalid
= FALSE
;
263 opcode
= &arc_table
[i
++];
265 if (ARC_SHORT (opcode
->mask
) && (insn_len
== 2))
267 if (OPCODE_AC (opcode
->opcode
) != OPCODE_AC (insn
[0]))
270 else if (!ARC_SHORT (opcode
->mask
) && (insn_len
== 4))
272 if (OPCODE (opcode
->opcode
) != OPCODE (insn
[0]))
278 if ((insn
[0] ^ opcode
->opcode
) & opcode
->mask
)
281 if (!(opcode
->cpu
& isa_mask
))
286 /* Possible candidate, check the operands. */
287 for (opidx
= opcode
->operands
; *opidx
; opidx
++)
290 const struct arc_operand
*operand
= &arc_operands
[*opidx
];
292 if (operand
->flags
& ARC_OPERAND_FAKE
)
295 if (operand
->extract
)
296 value
= (*operand
->extract
) (insn
[0], &invalid
);
298 value
= (insn
[0] >> operand
->shift
) & ((1 << operand
->bits
) - 1);
300 /* Check for LIMM indicator. If it is there, then make sure
301 we pick the right format. */
302 if (operand
->flags
& ARC_OPERAND_IR
303 && !(operand
->flags
& ARC_OPERAND_LIMM
))
305 if ((value
== 0x3E && insn_len
== 4)
306 || (value
== 0x1E && insn_len
== 2))
313 if (operand
->flags
& ARC_OPERAND_LIMM
314 && !(operand
->flags
& ARC_OPERAND_DUPLICATE
))
318 /* Check the flags. */
319 for (flgidx
= opcode
->flags
; *flgidx
; flgidx
++)
321 /* Get a valid flag class. */
322 const struct arc_flag_class
*cl_flags
= &arc_flag_classes
[*flgidx
];
323 const unsigned *flgopridx
;
324 int foundA
= 0, foundB
= 0;
327 /* Check first the extensions. */
328 if (cl_flags
->flag_class
& F_CLASS_EXTEND
)
330 value
= (insn
[0] & 0x1F);
331 if (arcExtMap_condCodeName (value
))
335 for (flgopridx
= cl_flags
->flags
; *flgopridx
; ++flgopridx
)
337 const struct arc_flag_operand
*flg_operand
=
338 &arc_flag_operands
[*flgopridx
];
340 value
= (insn
[0] >> flg_operand
->shift
)
341 & ((1 << flg_operand
->bits
) - 1);
342 if (value
== flg_operand
->code
)
348 if (!foundA
&& foundB
)
360 && skip_this_opcode (opcode
, info
))
363 /* The instruction is valid. */
366 while (opcode
->mask
);
371 /* Find long instructions matching values in INSN array. */
373 static const struct arc_long_opcode
*
374 find_format_long_instructions (unsigned *insn
,
375 unsigned int *insn_len
,
378 struct disassemble_info
*info
)
382 bfd_boolean limm_loaded
= FALSE
;
384 for (i
= 0; i
< arc_num_long_opcodes
; ++i
)
388 const struct arc_opcode
*opcode
;
390 opcode
= &arc_long_opcodes
[i
].base_opcode
;
392 if (ARC_SHORT (opcode
->mask
) && (*insn_len
== 2))
394 if (OPCODE_AC (opcode
->opcode
) != OPCODE_AC (insn
[0]))
397 else if (!ARC_SHORT (opcode
->mask
) && (*insn_len
== 4))
399 if (OPCODE (opcode
->opcode
) != OPCODE (insn
[0]))
405 if ((insn
[0] ^ opcode
->opcode
) & opcode
->mask
)
408 if (!(opcode
->cpu
& isa_mask
))
413 status
= (*info
->read_memory_func
) (memaddr
+ *insn_len
, buffer
,
418 limm
= ARRANGE_ENDIAN (info
, buffer
);
422 /* Check the second word using the mask and template. */
423 if ((limm
& arc_long_opcodes
[i
].limm_mask
)
424 != arc_long_opcodes
[i
].limm_template
)
429 return &arc_long_opcodes
[i
];
435 /* Find opcode for INSN, trying various different sources. The instruction
436 length in INSN_LEN will be updated if the instruction requires a LIMM
437 extension, and the additional values loaded into the INSN array (which
440 A pointer to the opcode is placed into OPCODE_RESULT, and ITER is
441 initialised, ready to iterate over the operands of the found opcode.
443 This function returns TRUE in almost all cases, FALSE is reserved to
444 indicate an error (failing to find an opcode is not an error) a
445 returned result of FALSE would indicate that the disassembler can't
448 If no matching opcode is found then the returned result will be TRUE,
449 the value placed into OPCODE_RESULT will be NULL, ITER will be
450 undefined, and INSN_LEN will be unchanged.
452 If a matching opcode is found, then the returned result will be TRUE,
453 the opcode pointer is placed into OPCODE_RESULT, INSN_LEN will be
454 increased by 4 if the instruction requires a LIMM, and the LIMM value
455 will have been loaded into the INSN[1]. Finally, ITER will have been
456 initialised so that calls to OPERAND_ITERATOR_NEXT will iterate over
457 the opcode's operands. */
460 find_format (bfd_vma memaddr
,
462 unsigned int * insn_len
,
464 struct disassemble_info
* info
,
465 const struct arc_opcode
** opcode_result
,
466 struct arc_operand_iterator
* iter
)
468 const struct arc_opcode
*opcode
= NULL
;
469 bfd_boolean needs_limm
;
470 const extInstruction_t
*einsn
;
472 /* First, try the extension instructions. */
473 einsn
= arcExtMap_insn (OPCODE (insn
[0]), insn
[0]);
476 const char *errmsg
= NULL
;
478 opcode
= arcExtMap_genOpcode (einsn
, isa_mask
, &errmsg
);
481 (*info
->fprintf_func
) (info
->stream
, "\
482 An error occured while generating the extension instruction operations");
483 *opcode_result
= NULL
;
487 opcode
= find_format_from_table (info
, opcode
, insn
, *insn_len
,
488 isa_mask
, &needs_limm
, FALSE
);
491 /* Then, try finding the first match in the opcode table. */
493 opcode
= find_format_from_table (info
, arc_opcodes
, insn
, *insn_len
,
494 isa_mask
, &needs_limm
, TRUE
);
496 if (needs_limm
&& opcode
!= NULL
)
501 status
= (*info
->read_memory_func
) (memaddr
+ *insn_len
, buffer
,
509 insn
[1] = ARRANGE_ENDIAN (info
, buffer
);
516 const struct arc_long_opcode
*long_opcode
;
518 /* No instruction found yet, try the long instructions. */
520 find_format_long_instructions (insn
, insn_len
, isa_mask
,
523 if (long_opcode
!= NULL
)
525 iter
->mode
= OPERAND_ITERATOR_LONG
;
527 iter
->state
.long_insn
.long_opcode
= long_opcode
;
528 iter
->state
.long_insn
.opidx_base
=
529 long_opcode
->base_opcode
.operands
;
530 iter
->state
.long_insn
.opidx_limm
=
531 long_opcode
->operands
;
532 opcode
= &long_opcode
->base_opcode
;
537 iter
->mode
= OPERAND_ITERATOR_STANDARD
;
539 iter
->state
.standard
.opcode
= opcode
;
540 iter
->state
.standard
.opidx
= opcode
->operands
;
543 *opcode_result
= opcode
;
548 print_flags (const struct arc_opcode
*opcode
,
550 struct disassemble_info
*info
)
552 const unsigned char *flgidx
;
555 /* Now extract and print the flags. */
556 for (flgidx
= opcode
->flags
; *flgidx
; flgidx
++)
558 /* Get a valid flag class. */
559 const struct arc_flag_class
*cl_flags
= &arc_flag_classes
[*flgidx
];
560 const unsigned *flgopridx
;
562 /* Check first the extensions. */
563 if (cl_flags
->flag_class
& F_CLASS_EXTEND
)
566 value
= (insn
[0] & 0x1F);
568 name
= arcExtMap_condCodeName (value
);
571 (*info
->fprintf_func
) (info
->stream
, ".%s", name
);
576 for (flgopridx
= cl_flags
->flags
; *flgopridx
; ++flgopridx
)
578 const struct arc_flag_operand
*flg_operand
=
579 &arc_flag_operands
[*flgopridx
];
581 if (!flg_operand
->favail
)
584 value
= (insn
[0] >> flg_operand
->shift
)
585 & ((1 << flg_operand
->bits
) - 1);
586 if (value
== flg_operand
->code
)
588 /* FIXME!: print correctly nt/t flag. */
589 if (!special_flag_p (opcode
->name
, flg_operand
->name
))
590 (*info
->fprintf_func
) (info
->stream
, ".");
591 else if (info
->insn_type
== dis_dref
)
593 switch (flg_operand
->name
[0])
607 if (flg_operand
->name
[0] == 'd'
608 && flg_operand
->name
[1] == 0)
609 info
->branch_delay_insns
= 1;
611 /* Check if it is a conditional flag. */
612 if (cl_flags
->flag_class
& F_CLASS_COND
)
614 if (info
->insn_type
== dis_jsr
)
615 info
->insn_type
= dis_condjsr
;
616 else if (info
->insn_type
== dis_branch
)
617 info
->insn_type
= dis_condbranch
;
620 (*info
->fprintf_func
) (info
->stream
, "%s", flg_operand
->name
);
627 get_auxreg (const struct arc_opcode
*opcode
,
633 const struct arc_aux_reg
*auxr
= &arc_aux_regs
[0];
635 if (opcode
->insn_class
!= AUXREG
)
638 name
= arcExtMap_auxRegName (value
);
642 for (i
= 0; i
< arc_num_aux_regs
; i
++, auxr
++)
644 if (!(auxr
->cpu
& isa_mask
))
647 if (auxr
->subclass
!= NONE
)
650 if (auxr
->address
== value
)
656 /* Calculate the instruction length for an instruction starting with MSB
657 and LSB, the most and least significant byte. The ISA_MASK is used to
658 filter the instructions considered to only those that are part of the
659 current architecture.
661 The instruction lengths are calculated from the ARC_OPCODE table, and
662 cached for later use. */
665 arc_insn_length (bfd_byte msb
, bfd_byte lsb
, struct disassemble_info
*info
)
667 bfd_byte major_opcode
= msb
>> 3;
671 case bfd_mach_arc_arc700
:
672 /* The nps400 extension set requires this special casing of the
673 instruction length calculation. Right now this is not causing any
674 problems as none of the known extensions overlap in opcode space,
675 but, if they ever do then we might need to start carrying
676 information around in the elf about which extensions are in use. */
677 if (major_opcode
== 0xb)
679 bfd_byte minor_opcode
= lsb
& 0x1f;
681 if (minor_opcode
< 4)
684 case bfd_mach_arc_arc600
:
685 return (major_opcode
> 0xb) ? 2 : 4;
688 case bfd_mach_arc_arcv2
:
689 return (major_opcode
> 0x7) ? 2 : 4;
697 /* Extract and return the value of OPERAND from the instruction whose value
698 is held in the array INSN. */
701 extract_operand_value (const struct arc_operand
*operand
, unsigned *insn
)
705 /* Read the limm operand, if required. */
706 if (operand
->flags
& ARC_OPERAND_LIMM
)
707 /* The second part of the instruction value will have been loaded as
708 part of the find_format call made earlier. */
712 if (operand
->extract
)
713 value
= (*operand
->extract
) (insn
[0], (int *) NULL
);
716 if (operand
->flags
& ARC_OPERAND_ALIGNED32
)
718 value
= (insn
[0] >> operand
->shift
)
719 & ((1 << (operand
->bits
- 2)) - 1);
724 value
= (insn
[0] >> operand
->shift
) & ((1 << operand
->bits
) - 1);
726 if (operand
->flags
& ARC_OPERAND_SIGNED
)
728 int signbit
= 1 << (operand
->bits
- 1);
729 value
= (value
^ signbit
) - signbit
;
737 /* Find the next operand, and the operands value from ITER. Return TRUE if
738 there is another operand, otherwise return FALSE. If there is an
739 operand returned then the operand is placed into OPERAND, and the value
740 into VALUE. If there is no operand returned then OPERAND and VALUE are
744 operand_iterator_next (struct arc_operand_iterator
*iter
,
745 const struct arc_operand
**operand
,
748 if (iter
->mode
== OPERAND_ITERATOR_STANDARD
)
750 if (*iter
->state
.standard
.opidx
== 0)
756 *operand
= &arc_operands
[*iter
->state
.standard
.opidx
];
757 *value
= extract_operand_value (*operand
, iter
->insn
);
758 iter
->state
.standard
.opidx
++;
762 const struct arc_operand
*operand_base
, *operand_limm
;
763 int value_base
, value_limm
;
765 if (*iter
->state
.long_insn
.opidx_limm
== 0)
771 operand_base
= &arc_operands
[*iter
->state
.long_insn
.opidx_base
];
772 operand_limm
= &arc_operands
[*iter
->state
.long_insn
.opidx_limm
];
774 if (operand_base
->flags
& ARC_OPERAND_LIMM
)
776 /* We've reached the end of the operand list. */
781 value_base
= value_limm
= 0;
782 if (!(operand_limm
->flags
& ARC_OPERAND_IGNORE
))
784 /* This should never happen. If it does then the use of
785 extract_operand_value below will access memory beyond
787 assert ((operand_limm
->flags
& ARC_OPERAND_LIMM
) == 0);
789 *operand
= operand_limm
;
790 value_limm
= extract_operand_value (*operand
, &iter
->insn
[1]);
793 if (!(operand_base
->flags
& ARC_OPERAND_IGNORE
))
795 *operand
= operand_base
;
796 value_base
= extract_operand_value (*operand
, iter
->insn
);
799 /* This is a bit of a fudge. There's no reason why simply ORing
800 together the two values is the right thing to do, however, for all
801 the cases we currently have, it is the right thing, so, for now,
802 I've put off solving the more complex problem. */
803 *value
= value_base
| value_limm
;
805 iter
->state
.long_insn
.opidx_base
++;
806 iter
->state
.long_insn
.opidx_limm
++;
811 /* Helper for parsing the options. */
814 parse_option (char *option
)
816 if (CONST_STRNEQ (option
, "dsp"))
817 add_to_decodelist (DSP
, NONE
);
819 else if (CONST_STRNEQ (option
, "spfp"))
820 add_to_decodelist (FLOAT
, SPX
);
822 else if (CONST_STRNEQ (option
, "dpfp"))
823 add_to_decodelist (FLOAT
, DPX
);
825 else if (CONST_STRNEQ (option
, "quarkse_em"))
826 add_to_decodelist (FLOAT
, QUARKSE
);
828 else if (CONST_STRNEQ (option
, "fpuda"))
829 add_to_decodelist (FLOAT
, DPA
);
831 else if (CONST_STRNEQ (option
, "fpud"))
833 add_to_decodelist (FLOAT
, SP
);
834 add_to_decodelist (FLOAT
, CVT
);
837 else if (CONST_STRNEQ (option
, "fpus"))
839 add_to_decodelist (FLOAT
, DP
);
840 add_to_decodelist (FLOAT
, CVT
);
843 fprintf (stderr
, _("Unrecognised disassembler option: %s\n"), option
);
846 /* Go over the options list and parse it. */
849 parse_disassembler_options (char *options
)
856 /* Skip empty options. */
863 parse_option (options
);
865 while (*options
!= ',' && *options
!= '\0')
870 /* Disassemble ARC instructions. */
873 print_insn_arc (bfd_vma memaddr
,
874 struct disassemble_info
*info
)
877 unsigned int lowbyte
, highbyte
;
879 unsigned int insn_len
;
880 unsigned insn
[2] = { 0, 0 };
882 const struct arc_opcode
*opcode
;
883 bfd_boolean need_comma
;
884 bfd_boolean open_braket
;
886 const struct arc_operand
*operand
;
888 struct arc_operand_iterator iter
;
889 Elf_Internal_Ehdr
*header
= NULL
;
891 if (info
->disassembler_options
)
893 parse_disassembler_options (info
->disassembler_options
);
895 /* Avoid repeated parsing of the options. */
896 info
->disassembler_options
= NULL
;
899 memset (&iter
, 0, sizeof (iter
));
900 lowbyte
= ((info
->endian
== BFD_ENDIAN_LITTLE
) ? 1 : 0);
901 highbyte
= ((info
->endian
== BFD_ENDIAN_LITTLE
) ? 0 : 1);
903 if (info
->section
&& info
->section
->owner
)
904 header
= elf_elfheader (info
->section
->owner
);
908 case bfd_mach_arc_arc700
:
909 isa_mask
= ARC_OPCODE_ARC700
;
912 case bfd_mach_arc_arc600
:
913 isa_mask
= ARC_OPCODE_ARC600
;
916 case bfd_mach_arc_arcv2
:
918 isa_mask
= ARC_OPCODE_ARCv2EM
;
919 if ((header
->e_flags
& EF_ARC_MACH_MSK
) == EF_ARC_CPU_ARCV2HS
)
921 isa_mask
= ARC_OPCODE_ARCv2HS
;
922 /* FPU instructions are not extensions for HS. */
923 add_to_decodelist (FLOAT
, SP
);
924 add_to_decodelist (FLOAT
, DP
);
925 add_to_decodelist (FLOAT
, CVT
);
930 /* This variable may be set by the instruction decoder. It suggests
931 the number of bytes objdump should display on a single line. If
932 the instruction decoder sets this, it should always set it to
933 the same value in order to get reasonable looking output. */
935 info
->bytes_per_line
= 8;
937 /* In the next lines, we set two info variables control the way
938 objdump displays the raw data. For example, if bytes_per_line is
939 8 and bytes_per_chunk is 4, the output will look like this:
940 00: 00000000 00000000
941 with the chunks displayed according to "display_endian". */
944 && !(info
->section
->flags
& SEC_CODE
))
946 /* This is not a CODE section. */
947 switch (info
->section
->size
)
952 size
= info
->section
->size
;
955 size
= (info
->section
->size
& 0x01) ? 1 : 4;
958 info
->bytes_per_chunk
= 1;
959 info
->display_endian
= info
->endian
;
964 info
->bytes_per_chunk
= 2;
965 info
->display_endian
= info
->endian
;
968 /* Read the insn into a host word. */
969 status
= (*info
->read_memory_func
) (memaddr
, buffer
, size
, info
);
972 (*info
->memory_error_func
) (status
, memaddr
, info
);
977 && !(info
->section
->flags
& SEC_CODE
))
982 data
= bfd_get_bits (buffer
, size
* 8,
983 info
->display_endian
== BFD_ENDIAN_BIG
);
987 (*info
->fprintf_func
) (info
->stream
, ".byte\t0x%02lx", data
);
990 (*info
->fprintf_func
) (info
->stream
, ".short\t0x%04lx", data
);
993 (*info
->fprintf_func
) (info
->stream
, ".word\t0x%08lx", data
);
1001 insn_len
= arc_insn_length (buffer
[lowbyte
], buffer
[highbyte
], info
);
1002 pr_debug ("instruction length = %d bytes\n", insn_len
);
1007 insn
[0] = (buffer
[lowbyte
] << 8) | buffer
[highbyte
];
1011 /* An unknown instruction is treated as being length 4. This is
1012 possibly not the best solution, but matches the behaviour that was
1013 in place before the table based instruction length look-up was
1016 /* This is a long instruction: Read the remaning 2 bytes. */
1017 status
= (*info
->read_memory_func
) (memaddr
+ 2, &buffer
[2], 2, info
);
1020 (*info
->memory_error_func
) (status
, memaddr
+ 2, info
);
1023 insn
[0] = ARRANGE_ENDIAN (info
, buffer
);
1027 /* Set some defaults for the insn info. */
1028 info
->insn_info_valid
= 1;
1029 info
->branch_delay_insns
= 0;
1030 info
->data_size
= 0;
1031 info
->insn_type
= dis_nonbranch
;
1035 /* FIXME to be moved in dissasemble_init_for_target. */
1036 info
->disassembler_needs_relocs
= TRUE
;
1038 /* Find the first match in the opcode table. */
1039 if (!find_format (memaddr
, insn
, &insn_len
, isa_mask
, info
, &opcode
, &iter
))
1045 (*info
->fprintf_func
) (info
->stream
, ".long %#04x", insn
[0]);
1047 (*info
->fprintf_func
) (info
->stream
, ".long %#08x", insn
[0]);
1049 info
->insn_type
= dis_noninsn
;
1053 /* Print the mnemonic. */
1054 (*info
->fprintf_func
) (info
->stream
, "%s", opcode
->name
);
1056 /* Preselect the insn class. */
1057 switch (opcode
->insn_class
)
1061 if (!strncmp (opcode
->name
, "bl", 2)
1062 || !strncmp (opcode
->name
, "jl", 2))
1064 if (opcode
->subclass
== COND
)
1065 info
->insn_type
= dis_condjsr
;
1067 info
->insn_type
= dis_jsr
;
1071 if (opcode
->subclass
== COND
)
1072 info
->insn_type
= dis_condbranch
;
1074 info
->insn_type
= dis_branch
;
1078 info
->insn_type
= dis_dref
; /* FIXME! DB indicates mov as memory! */
1081 info
->insn_type
= dis_nonbranch
;
1085 pr_debug ("%s: 0x%08x\n", opcode
->name
, opcode
->opcode
);
1087 print_flags (opcode
, insn
, info
);
1089 if (opcode
->operands
[0] != 0)
1090 (*info
->fprintf_func
) (info
->stream
, "\t");
1093 open_braket
= FALSE
;
1095 /* Now extract and print the operands. */
1097 while (operand_iterator_next (&iter
, &operand
, &value
))
1099 if (open_braket
&& (operand
->flags
& ARC_OPERAND_BRAKET
))
1101 (*info
->fprintf_func
) (info
->stream
, "]");
1102 open_braket
= FALSE
;
1106 /* Only take input from real operands. */
1107 if ((operand
->flags
& ARC_OPERAND_FAKE
)
1108 && !(operand
->flags
& ARC_OPERAND_BRAKET
))
1111 if ((operand
->flags
& ARC_OPERAND_IGNORE
)
1112 && (operand
->flags
& ARC_OPERAND_IR
)
1117 (*info
->fprintf_func
) (info
->stream
, ",");
1119 if (!open_braket
&& (operand
->flags
& ARC_OPERAND_BRAKET
))
1121 (*info
->fprintf_func
) (info
->stream
, "[");
1127 /* Print the operand as directed by the flags. */
1128 if (operand
->flags
& ARC_OPERAND_IR
)
1132 assert (value
>=0 && value
< 64);
1133 rname
= arcExtMap_coreRegName (value
);
1135 rname
= regnames
[value
];
1136 (*info
->fprintf_func
) (info
->stream
, "%s", rname
);
1137 if (operand
->flags
& ARC_OPERAND_TRUNCATE
)
1139 rname
= arcExtMap_coreRegName (value
+ 1);
1141 rname
= regnames
[value
+ 1];
1142 (*info
->fprintf_func
) (info
->stream
, "%s", rname
);
1145 else if (operand
->flags
& ARC_OPERAND_LIMM
)
1147 const char *rname
= get_auxreg (opcode
, value
, isa_mask
);
1148 if (rname
&& open_braket
)
1149 (*info
->fprintf_func
) (info
->stream
, "%s", rname
);
1152 (*info
->fprintf_func
) (info
->stream
, "%#x", value
);
1153 if (info
->insn_type
== dis_branch
1154 || info
->insn_type
== dis_jsr
)
1155 info
->target
= (bfd_vma
) value
;
1158 else if (operand
->flags
& ARC_OPERAND_PCREL
)
1161 if (info
->flags
& INSN_HAS_RELOC
)
1163 (*info
->print_address_func
) ((memaddr
& ~3) + value
, info
);
1165 info
->target
= (bfd_vma
) (memaddr
& ~3) + value
;
1167 else if (operand
->flags
& ARC_OPERAND_SIGNED
)
1169 const char *rname
= get_auxreg (opcode
, value
, isa_mask
);
1170 if (rname
&& open_braket
)
1171 (*info
->fprintf_func
) (info
->stream
, "%s", rname
);
1173 (*info
->fprintf_func
) (info
->stream
, "%d", value
);
1177 if (operand
->flags
& ARC_OPERAND_TRUNCATE
1178 && !(operand
->flags
& ARC_OPERAND_ALIGNED32
)
1179 && !(operand
->flags
& ARC_OPERAND_ALIGNED16
)
1180 && value
> 0 && value
<= 14)
1181 (*info
->fprintf_func
) (info
->stream
, "r13-%s",
1182 regnames
[13 + value
- 1]);
1185 const char *rname
= get_auxreg (opcode
, value
, isa_mask
);
1186 if (rname
&& open_braket
)
1187 (*info
->fprintf_func
) (info
->stream
, "%s", rname
);
1189 (*info
->fprintf_func
) (info
->stream
, "%#x", value
);
1201 arc_get_disassembler (bfd
*abfd
)
1203 /* Read the extenssion insns and registers, if any. */
1204 build_ARC_extmap (abfd
);
1209 return print_insn_arc
;
1212 /* Disassemble ARC instructions. Used by debugger. */
1215 arcAnalyzeInstr (bfd_vma memaddr
,
1216 struct disassemble_info
*info
)
1218 struct arcDisState ret
;
1219 memset (&ret
, 0, sizeof (struct arcDisState
));
1221 ret
.instructionLen
= print_insn_arc (memaddr
, info
);
1224 ret
.words
[0] = insn
[0];
1225 ret
.words
[1] = insn
[1];
1227 ret
.coreRegName
= _coreRegName
;
1228 ret
.auxRegName
= _auxRegName
;
1229 ret
.condCodeName
= _condCodeName
;
1230 ret
.instName
= _instName
;
1237 print_arc_disassembler_options (FILE *stream
)
1239 fprintf (stream
, _("\n\
1240 The following ARC specific disassembler options are supported for use \n\
1241 with -M switch (multiple options should be separated by commas):\n"));
1243 fprintf (stream
, _("\
1244 dsp Recognize DSP instructions.\n"));
1245 fprintf (stream
, _("\
1246 spfp Recognize FPX SP instructions.\n"));
1247 fprintf (stream
, _("\
1248 dpfp Recognize FPX DP instructions.\n"));
1249 fprintf (stream
, _("\
1250 quarkse_em Recognize FPU QuarkSE-EM instructions.\n"));
1251 fprintf (stream
, _("\
1252 fpuda Recognize double assist FPU instructions.\n"));
1253 fprintf (stream
, _("\
1254 fpus Recognize single precision FPU instructions.\n"));
1255 fprintf (stream
, _("\
1256 fpud Recognize double precision FPU instructions.\n"));
1261 eval: (c-set-style "gnu")