1 /* aarch64-dis.c -- AArch64 disassembler.
2 Copyright (C) 2009-2016 Free Software Foundation, Inc.
3 Contributed by ARM Ltd.
5 This file is part of the GNU opcodes library.
7 This library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 It is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; see the file COPYING3. If not,
19 see <http://www.gnu.org/licenses/>. */
22 #include "bfd_stdint.h"
24 #include "libiberty.h"
26 #include "aarch64-dis.h"
36 /* Cached mapping symbol state. */
43 static enum map_type last_type;
44 static int last_mapping_sym = -1;
45 static bfd_vma last_mapping_addr = 0;
48 static int no_aliases = 0; /* If set disassemble as most general inst. */
52 set_default_aarch64_dis_options (struct disassemble_info *info ATTRIBUTE_UNUSED)
57 parse_aarch64_dis_option (const char *option, unsigned int len ATTRIBUTE_UNUSED)
59 /* Try to match options that are simple flags */
60 if (CONST_STRNEQ (option, "no-aliases"))
66 if (CONST_STRNEQ (option, "aliases"))
73 if (CONST_STRNEQ (option, "debug_dump"))
78 #endif /* DEBUG_AARCH64 */
81 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
85 parse_aarch64_dis_options (const char *options)
87 const char *option_end;
92 while (*options != '\0')
94 /* Skip empty options. */
101 /* We know that *options is neither NUL or a comma. */
102 option_end = options + 1;
103 while (*option_end != ',' && *option_end != '\0')
106 parse_aarch64_dis_option (options, option_end - options);
108 /* Go on to the next one. If option_end points to a comma, it
109 will be skipped above. */
110 options = option_end;
114 /* Functions doing the instruction disassembling. */
116 /* The unnamed arguments consist of the number of fields and information about
117 these fields where the VALUE will be extracted from CODE and returned.
118 MASK can be zero or the base mask of the opcode.
120 N.B. the fields are required to be in such an order than the most signficant
121 field for VALUE comes the first, e.g. the <index> in
122 SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
123 is encoded in H:L:M in some cases, the fields H:L:M should be passed in
124 the order of H, L, M. */
126 static inline aarch64_insn
127 extract_fields (aarch64_insn code, aarch64_insn mask, ...)
130 const aarch64_field *field;
131 enum aarch64_field_kind kind;
135 num = va_arg (va, uint32_t);
137 aarch64_insn value = 0x0;
140 kind = va_arg (va, enum aarch64_field_kind);
141 field = &fields[kind];
142 value <<= field->width;
143 value |= extract_field (kind, code, mask);
148 /* Sign-extend bit I of VALUE. */
149 static inline int32_t
150 sign_extend (aarch64_insn value, unsigned i)
152 uint32_t ret = value;
155 if ((value >> i) & 0x1)
157 uint32_t val = (uint32_t)(-1) << i;
160 return (int32_t) ret;
163 /* N.B. the following inline helpfer functions create a dependency on the
164 order of operand qualifier enumerators. */
166 /* Given VALUE, return qualifier for a general purpose register. */
167 static inline enum aarch64_opnd_qualifier
168 get_greg_qualifier_from_value (aarch64_insn value)
170 enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_W + value;
172 && aarch64_get_qualifier_standard_value (qualifier) == value);
176 /* Given VALUE, return qualifier for a vector register. This does not support
177 decoding instructions that accept the 2H vector type. */
179 static inline enum aarch64_opnd_qualifier
180 get_vreg_qualifier_from_value (aarch64_insn value)
182 enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_V_8B + value;
184 /* Instructions using vector type 2H should not call this function. Skip over
186 if (qualifier >= AARCH64_OPND_QLF_V_2H)
190 && aarch64_get_qualifier_standard_value (qualifier) == value);
194 /* Given VALUE, return qualifier for an FP or AdvSIMD scalar register. */
195 static inline enum aarch64_opnd_qualifier
196 get_sreg_qualifier_from_value (aarch64_insn value)
198 enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_S_B + value;
201 && aarch64_get_qualifier_standard_value (qualifier) == value);
205 /* Given the instruction in *INST which is probably half way through the
206 decoding and our caller wants to know the expected qualifier for operand
207 I. Return such a qualifier if we can establish it; otherwise return
208 AARCH64_OPND_QLF_NIL. */
210 static aarch64_opnd_qualifier_t
211 get_expected_qualifier (const aarch64_inst *inst, int i)
213 aarch64_opnd_qualifier_seq_t qualifiers;
214 /* Should not be called if the qualifier is known. */
215 assert (inst->operands[i].qualifier == AARCH64_OPND_QLF_NIL);
216 if (aarch64_find_best_match (inst, inst->opcode->qualifiers_list,
218 return qualifiers[i];
220 return AARCH64_OPND_QLF_NIL;
223 /* Operand extractors. */
226 aarch64_ext_regno (const aarch64_operand *self, aarch64_opnd_info *info,
227 const aarch64_insn code,
228 const aarch64_inst *inst ATTRIBUTE_UNUSED)
230 info->reg.regno = extract_field (self->fields[0], code, 0);
235 aarch64_ext_regno_pair (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info,
236 const aarch64_insn code ATTRIBUTE_UNUSED,
237 const aarch64_inst *inst ATTRIBUTE_UNUSED)
239 assert (info->idx == 1
241 info->reg.regno = inst->operands[info->idx - 1].reg.regno + 1;
245 /* e.g. IC <ic_op>{, <Xt>}. */
247 aarch64_ext_regrt_sysins (const aarch64_operand *self, aarch64_opnd_info *info,
248 const aarch64_insn code,
249 const aarch64_inst *inst ATTRIBUTE_UNUSED)
251 info->reg.regno = extract_field (self->fields[0], code, 0);
252 assert (info->idx == 1
253 && (aarch64_get_operand_class (inst->operands[0].type)
254 == AARCH64_OPND_CLASS_SYSTEM));
255 /* This will make the constraint checking happy and more importantly will
256 help the disassembler determine whether this operand is optional or
258 info->present = aarch64_sys_ins_reg_has_xt (inst->operands[0].sysins_op);
263 /* e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]. */
265 aarch64_ext_reglane (const aarch64_operand *self, aarch64_opnd_info *info,
266 const aarch64_insn code,
267 const aarch64_inst *inst ATTRIBUTE_UNUSED)
270 info->reglane.regno = extract_field (self->fields[0], code,
273 /* Index and/or type. */
274 if (inst->opcode->iclass == asisdone
275 || inst->opcode->iclass == asimdins)
277 if (info->type == AARCH64_OPND_En
278 && inst->opcode->operands[0] == AARCH64_OPND_Ed)
281 /* index2 for e.g. INS <Vd>.<Ts>[<index1>], <Vn>.<Ts>[<index2>]. */
282 assert (info->idx == 1); /* Vn */
283 aarch64_insn value = extract_field (FLD_imm4, code, 0);
284 /* Depend on AARCH64_OPND_Ed to determine the qualifier. */
285 info->qualifier = get_expected_qualifier (inst, info->idx);
286 shift = get_logsz (aarch64_get_qualifier_esize (info->qualifier));
287 info->reglane.index = value >> shift;
291 /* index and type for e.g. DUP <V><d>, <Vn>.<T>[<index>].
299 aarch64_insn value = extract_field (FLD_imm5, code, 0);
300 while (++pos <= 3 && (value & 0x1) == 0)
304 info->qualifier = get_sreg_qualifier_from_value (pos);
305 info->reglane.index = (unsigned) (value >> 1);
310 /* Index only for e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
311 or SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]. */
313 /* Need information in other operand(s) to help decoding. */
314 info->qualifier = get_expected_qualifier (inst, info->idx);
315 switch (info->qualifier)
317 case AARCH64_OPND_QLF_S_H:
319 info->reglane.index = extract_fields (code, 0, 3, FLD_H, FLD_L,
321 info->reglane.regno &= 0xf;
323 case AARCH64_OPND_QLF_S_S:
325 info->reglane.index = extract_fields (code, 0, 2, FLD_H, FLD_L);
327 case AARCH64_OPND_QLF_S_D:
329 info->reglane.index = extract_field (FLD_H, code, 0);
340 aarch64_ext_reglist (const aarch64_operand *self, aarch64_opnd_info *info,
341 const aarch64_insn code,
342 const aarch64_inst *inst ATTRIBUTE_UNUSED)
345 info->reglist.first_regno = extract_field (self->fields[0], code, 0);
347 info->reglist.num_regs = extract_field (FLD_len, code, 0) + 1;
351 /* Decode Rt and opcode fields of Vt in AdvSIMD load/store instructions. */
353 aarch64_ext_ldst_reglist (const aarch64_operand *self ATTRIBUTE_UNUSED,
354 aarch64_opnd_info *info, const aarch64_insn code,
355 const aarch64_inst *inst)
358 /* Number of elements in each structure to be loaded/stored. */
359 unsigned expected_num = get_opcode_dependent_value (inst->opcode);
363 unsigned is_reserved;
365 unsigned num_elements;
381 info->reglist.first_regno = extract_field (FLD_Rt, code, 0);
383 value = extract_field (FLD_opcode, code, 0);
384 if (expected_num != data[value].num_elements || data[value].is_reserved)
386 info->reglist.num_regs = data[value].num_regs;
391 /* Decode Rt and S fields of Vt in AdvSIMD load single structure to all
392 lanes instructions. */
394 aarch64_ext_ldst_reglist_r (const aarch64_operand *self ATTRIBUTE_UNUSED,
395 aarch64_opnd_info *info, const aarch64_insn code,
396 const aarch64_inst *inst)
401 info->reglist.first_regno = extract_field (FLD_Rt, code, 0);
403 value = extract_field (FLD_S, code, 0);
405 /* Number of registers is equal to the number of elements in
406 each structure to be loaded/stored. */
407 info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
408 assert (info->reglist.num_regs >= 1 && info->reglist.num_regs <= 4);
410 /* Except when it is LD1R. */
411 if (info->reglist.num_regs == 1 && value == (aarch64_insn) 1)
412 info->reglist.num_regs = 2;
417 /* Decode Q, opcode<2:1>, S, size and Rt fields of Vt in AdvSIMD
418 load/store single element instructions. */
420 aarch64_ext_ldst_elemlist (const aarch64_operand *self ATTRIBUTE_UNUSED,
421 aarch64_opnd_info *info, const aarch64_insn code,
422 const aarch64_inst *inst ATTRIBUTE_UNUSED)
424 aarch64_field field = {0, 0};
425 aarch64_insn QSsize; /* fields Q:S:size. */
426 aarch64_insn opcodeh2; /* opcode<2:1> */
429 info->reglist.first_regno = extract_field (FLD_Rt, code, 0);
431 /* Decode the index, opcode<2:1> and size. */
432 gen_sub_field (FLD_asisdlso_opcode, 1, 2, &field);
433 opcodeh2 = extract_field_2 (&field, code, 0);
434 QSsize = extract_fields (code, 0, 3, FLD_Q, FLD_S, FLD_vldst_size);
438 info->qualifier = AARCH64_OPND_QLF_S_B;
439 /* Index encoded in "Q:S:size". */
440 info->reglist.index = QSsize;
446 info->qualifier = AARCH64_OPND_QLF_S_H;
447 /* Index encoded in "Q:S:size<1>". */
448 info->reglist.index = QSsize >> 1;
451 if ((QSsize >> 1) & 0x1)
454 if ((QSsize & 0x1) == 0)
456 info->qualifier = AARCH64_OPND_QLF_S_S;
457 /* Index encoded in "Q:S". */
458 info->reglist.index = QSsize >> 2;
462 if (extract_field (FLD_S, code, 0))
465 info->qualifier = AARCH64_OPND_QLF_S_D;
466 /* Index encoded in "Q". */
467 info->reglist.index = QSsize >> 3;
474 info->reglist.has_index = 1;
475 info->reglist.num_regs = 0;
476 /* Number of registers is equal to the number of elements in
477 each structure to be loaded/stored. */
478 info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
479 assert (info->reglist.num_regs >= 1 && info->reglist.num_regs <= 4);
484 /* Decode fields immh:immb and/or Q for e.g.
485 SSHR <Vd>.<T>, <Vn>.<T>, #<shift>
486 or SSHR <V><d>, <V><n>, #<shift>. */
489 aarch64_ext_advsimd_imm_shift (const aarch64_operand *self ATTRIBUTE_UNUSED,
490 aarch64_opnd_info *info, const aarch64_insn code,
491 const aarch64_inst *inst)
494 aarch64_insn Q, imm, immh;
495 enum aarch64_insn_class iclass = inst->opcode->iclass;
497 immh = extract_field (FLD_immh, code, 0);
500 imm = extract_fields (code, 0, 2, FLD_immh, FLD_immb);
502 /* Get highest set bit in immh. */
503 while (--pos >= 0 && (immh & 0x8) == 0)
506 assert ((iclass == asimdshf || iclass == asisdshf)
507 && (info->type == AARCH64_OPND_IMM_VLSR
508 || info->type == AARCH64_OPND_IMM_VLSL));
510 if (iclass == asimdshf)
512 Q = extract_field (FLD_Q, code, 0);
514 0000 x SEE AdvSIMD modified immediate
524 get_vreg_qualifier_from_value ((pos << 1) | (int) Q);
527 info->qualifier = get_sreg_qualifier_from_value (pos);
529 if (info->type == AARCH64_OPND_IMM_VLSR)
531 0000 SEE AdvSIMD modified immediate
532 0001 (16-UInt(immh:immb))
533 001x (32-UInt(immh:immb))
534 01xx (64-UInt(immh:immb))
535 1xxx (128-UInt(immh:immb)) */
536 info->imm.value = (16 << pos) - imm;
540 0000 SEE AdvSIMD modified immediate
541 0001 (UInt(immh:immb)-8)
542 001x (UInt(immh:immb)-16)
543 01xx (UInt(immh:immb)-32)
544 1xxx (UInt(immh:immb)-64) */
545 info->imm.value = imm - (8 << pos);
550 /* Decode shift immediate for e.g. sshr (imm). */
552 aarch64_ext_shll_imm (const aarch64_operand *self ATTRIBUTE_UNUSED,
553 aarch64_opnd_info *info, const aarch64_insn code,
554 const aarch64_inst *inst ATTRIBUTE_UNUSED)
558 val = extract_field (FLD_size, code, 0);
561 case 0: imm = 8; break;
562 case 1: imm = 16; break;
563 case 2: imm = 32; break;
566 info->imm.value = imm;
570 /* Decode imm for e.g. BFM <Wd>, <Wn>, #<immr>, #<imms>.
571 value in the field(s) will be extracted as unsigned immediate value. */
573 aarch64_ext_imm (const aarch64_operand *self, aarch64_opnd_info *info,
574 const aarch64_insn code,
575 const aarch64_inst *inst ATTRIBUTE_UNUSED)
578 /* Maximum of two fields to extract. */
579 assert (self->fields[2] == FLD_NIL);
581 if (self->fields[1] == FLD_NIL)
582 imm = extract_field (self->fields[0], code, 0);
584 /* e.g. TBZ b5:b40. */
585 imm = extract_fields (code, 0, 2, self->fields[0], self->fields[1]);
587 if (info->type == AARCH64_OPND_FPIMM)
590 if (operand_need_sign_extension (self))
591 imm = sign_extend (imm, get_operand_fields_width (self) - 1);
593 if (operand_need_shift_by_two (self))
596 if (info->type == AARCH64_OPND_ADDR_ADRP)
599 info->imm.value = imm;
603 /* Decode imm and its shifter for e.g. MOVZ <Wd>, #<imm16>{, LSL #<shift>}. */
605 aarch64_ext_imm_half (const aarch64_operand *self, aarch64_opnd_info *info,
606 const aarch64_insn code,
607 const aarch64_inst *inst ATTRIBUTE_UNUSED)
609 aarch64_ext_imm (self, info, code, inst);
610 info->shifter.kind = AARCH64_MOD_LSL;
611 info->shifter.amount = extract_field (FLD_hw, code, 0) << 4;
615 /* Decode cmode and "a:b:c:d:e:f:g:h" for e.g.
616 MOVI <Vd>.<T>, #<imm8> {, LSL #<amount>}. */
618 aarch64_ext_advsimd_imm_modified (const aarch64_operand *self ATTRIBUTE_UNUSED,
619 aarch64_opnd_info *info,
620 const aarch64_insn code,
621 const aarch64_inst *inst ATTRIBUTE_UNUSED)
624 enum aarch64_opnd_qualifier opnd0_qualifier = inst->operands[0].qualifier;
625 aarch64_field field = {0, 0};
627 assert (info->idx == 1);
629 if (info->type == AARCH64_OPND_SIMD_FPIMM)
632 /* a:b:c:d:e:f:g:h */
633 imm = extract_fields (code, 0, 2, FLD_abc, FLD_defgh);
634 if (!info->imm.is_fp && aarch64_get_qualifier_esize (opnd0_qualifier) == 8)
636 /* Either MOVI <Dd>, #<imm>
637 or MOVI <Vd>.2D, #<imm>.
638 <imm> is a 64-bit immediate
639 'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh',
640 encoded in "a:b:c:d:e:f:g:h". */
642 unsigned abcdefgh = imm;
643 for (imm = 0ull, i = 0; i < 8; i++)
644 if (((abcdefgh >> i) & 0x1) != 0)
645 imm |= 0xffull << (8 * i);
647 info->imm.value = imm;
650 info->qualifier = get_expected_qualifier (inst, info->idx);
651 switch (info->qualifier)
653 case AARCH64_OPND_QLF_NIL:
655 info->shifter.kind = AARCH64_MOD_NONE;
657 case AARCH64_OPND_QLF_LSL:
659 info->shifter.kind = AARCH64_MOD_LSL;
660 switch (aarch64_get_qualifier_esize (opnd0_qualifier))
662 case 4: gen_sub_field (FLD_cmode, 1, 2, &field); break; /* per word */
663 case 2: gen_sub_field (FLD_cmode, 1, 1, &field); break; /* per half */
664 case 1: gen_sub_field (FLD_cmode, 1, 0, &field); break; /* per byte */
665 default: assert (0); return 0;
667 /* 00: 0; 01: 8; 10:16; 11:24. */
668 info->shifter.amount = extract_field_2 (&field, code, 0) << 3;
670 case AARCH64_OPND_QLF_MSL:
672 info->shifter.kind = AARCH64_MOD_MSL;
673 gen_sub_field (FLD_cmode, 0, 1, &field); /* per word */
674 info->shifter.amount = extract_field_2 (&field, code, 0) ? 16 : 8;
684 /* Decode scale for e.g. SCVTF <Dd>, <Wn>, #<fbits>. */
686 aarch64_ext_fbits (const aarch64_operand *self ATTRIBUTE_UNUSED,
687 aarch64_opnd_info *info, const aarch64_insn code,
688 const aarch64_inst *inst ATTRIBUTE_UNUSED)
690 info->imm.value = 64- extract_field (FLD_scale, code, 0);
694 /* Decode arithmetic immediate for e.g.
695 SUBS <Wd>, <Wn|WSP>, #<imm> {, <shift>}. */
697 aarch64_ext_aimm (const aarch64_operand *self ATTRIBUTE_UNUSED,
698 aarch64_opnd_info *info, const aarch64_insn code,
699 const aarch64_inst *inst ATTRIBUTE_UNUSED)
703 info->shifter.kind = AARCH64_MOD_LSL;
705 value = extract_field (FLD_shift, code, 0);
708 info->shifter.amount = value ? 12 : 0;
709 /* imm12 (unsigned) */
710 info->imm.value = extract_field (FLD_imm12, code, 0);
715 /* Decode logical immediate for e.g. ORR <Wd|WSP>, <Wn>, #<imm>. */
718 aarch64_ext_limm (const aarch64_operand *self ATTRIBUTE_UNUSED,
719 aarch64_opnd_info *info, const aarch64_insn code,
720 const aarch64_inst *inst ATTRIBUTE_UNUSED)
728 value = extract_fields (code, 0, 3, FLD_N, FLD_immr, FLD_imms);
729 assert (inst->operands[0].qualifier == AARCH64_OPND_QLF_W
730 || inst->operands[0].qualifier == AARCH64_OPND_QLF_X);
731 sf = aarch64_get_qualifier_esize (inst->operands[0].qualifier) != 4;
733 /* value is N:immr:imms. */
735 R = (value >> 6) & 0x3f;
736 N = (value >> 12) & 0x1;
738 if (sf == 0 && N == 1)
741 /* The immediate value is S+1 bits to 1, left rotated by SIMDsize - R
742 (in other words, right rotated by R), then replicated. */
746 mask = 0xffffffffffffffffull;
752 case 0x00 ... 0x1f: /* 0xxxxx */ simd_size = 32; break;
753 case 0x20 ... 0x2f: /* 10xxxx */ simd_size = 16; S &= 0xf; break;
754 case 0x30 ... 0x37: /* 110xxx */ simd_size = 8; S &= 0x7; break;
755 case 0x38 ... 0x3b: /* 1110xx */ simd_size = 4; S &= 0x3; break;
756 case 0x3c ... 0x3d: /* 11110x */ simd_size = 2; S &= 0x1; break;
759 mask = (1ull << simd_size) - 1;
760 /* Top bits are IGNORED. */
763 /* NOTE: if S = simd_size - 1 we get 0xf..f which is rejected. */
764 if (S == simd_size - 1)
766 /* S+1 consecutive bits to 1. */
767 /* NOTE: S can't be 63 due to detection above. */
768 imm = (1ull << (S + 1)) - 1;
769 /* Rotate to the left by simd_size - R. */
771 imm = ((imm << (simd_size - R)) & mask) | (imm >> R);
772 /* Replicate the value according to SIMD size. */
775 case 2: imm = (imm << 2) | imm;
776 case 4: imm = (imm << 4) | imm;
777 case 8: imm = (imm << 8) | imm;
778 case 16: imm = (imm << 16) | imm;
779 case 32: imm = (imm << 32) | imm;
781 default: assert (0); return 0;
784 info->imm.value = sf ? imm : imm & 0xffffffff;
789 /* Decode Ft for e.g. STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]
790 or LDP <Qt1>, <Qt2>, [<Xn|SP>], #<imm>. */
792 aarch64_ext_ft (const aarch64_operand *self ATTRIBUTE_UNUSED,
793 aarch64_opnd_info *info,
794 const aarch64_insn code, const aarch64_inst *inst)
799 info->reg.regno = extract_field (FLD_Rt, code, 0);
802 value = extract_field (FLD_ldst_size, code, 0);
803 if (inst->opcode->iclass == ldstpair_indexed
804 || inst->opcode->iclass == ldstnapair_offs
805 || inst->opcode->iclass == ldstpair_off
806 || inst->opcode->iclass == loadlit)
808 enum aarch64_opnd_qualifier qualifier;
811 case 0: qualifier = AARCH64_OPND_QLF_S_S; break;
812 case 1: qualifier = AARCH64_OPND_QLF_S_D; break;
813 case 2: qualifier = AARCH64_OPND_QLF_S_Q; break;
816 info->qualifier = qualifier;
821 value = extract_fields (code, 0, 2, FLD_opc1, FLD_ldst_size);
824 info->qualifier = get_sreg_qualifier_from_value (value);
830 /* Decode the address operand for e.g. STXRB <Ws>, <Wt>, [<Xn|SP>{,#0}]. */
832 aarch64_ext_addr_simple (const aarch64_operand *self ATTRIBUTE_UNUSED,
833 aarch64_opnd_info *info,
835 const aarch64_inst *inst ATTRIBUTE_UNUSED)
838 info->addr.base_regno = extract_field (FLD_Rn, code, 0);
842 /* Decode the address operand for e.g.
843 STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]. */
845 aarch64_ext_addr_regoff (const aarch64_operand *self ATTRIBUTE_UNUSED,
846 aarch64_opnd_info *info,
847 aarch64_insn code, const aarch64_inst *inst)
849 aarch64_insn S, value;
852 info->addr.base_regno = extract_field (FLD_Rn, code, 0);
854 info->addr.offset.regno = extract_field (FLD_Rm, code, 0);
856 value = extract_field (FLD_option, code, 0);
858 aarch64_get_operand_modifier_from_value (value, TRUE /* extend_p */);
859 /* Fix-up the shifter kind; although the table-driven approach is
860 efficient, it is slightly inflexible, thus needing this fix-up. */
861 if (info->shifter.kind == AARCH64_MOD_UXTX)
862 info->shifter.kind = AARCH64_MOD_LSL;
864 S = extract_field (FLD_S, code, 0);
867 info->shifter.amount = 0;
868 info->shifter.amount_present = 0;
873 /* Need information in other operand(s) to help achieve the decoding
875 info->qualifier = get_expected_qualifier (inst, info->idx);
876 /* Get the size of the data element that is accessed, which may be
877 different from that of the source register size, e.g. in strb/ldrb. */
878 size = aarch64_get_qualifier_esize (info->qualifier);
879 info->shifter.amount = get_logsz (size);
880 info->shifter.amount_present = 1;
886 /* Decode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>], #<simm>. */
888 aarch64_ext_addr_simm (const aarch64_operand *self, aarch64_opnd_info *info,
889 aarch64_insn code, const aarch64_inst *inst)
892 info->qualifier = get_expected_qualifier (inst, info->idx);
895 info->addr.base_regno = extract_field (FLD_Rn, code, 0);
896 /* simm (imm9 or imm7) */
897 imm = extract_field (self->fields[0], code, 0);
898 info->addr.offset.imm = sign_extend (imm, fields[self->fields[0]].width - 1);
899 if (self->fields[0] == FLD_imm7)
900 /* scaled immediate in ld/st pair instructions. */
901 info->addr.offset.imm *= aarch64_get_qualifier_esize (info->qualifier);
903 if (inst->opcode->iclass == ldst_unscaled
904 || inst->opcode->iclass == ldstnapair_offs
905 || inst->opcode->iclass == ldstpair_off
906 || inst->opcode->iclass == ldst_unpriv)
907 info->addr.writeback = 0;
910 /* pre/post- index */
911 info->addr.writeback = 1;
912 if (extract_field (self->fields[1], code, 0) == 1)
913 info->addr.preind = 1;
915 info->addr.postind = 1;
921 /* Decode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>{, #<simm>}]. */
923 aarch64_ext_addr_uimm12 (const aarch64_operand *self, aarch64_opnd_info *info,
925 const aarch64_inst *inst ATTRIBUTE_UNUSED)
928 info->qualifier = get_expected_qualifier (inst, info->idx);
929 shift = get_logsz (aarch64_get_qualifier_esize (info->qualifier));
931 info->addr.base_regno = extract_field (self->fields[0], code, 0);
933 info->addr.offset.imm = extract_field (self->fields[1], code, 0) << shift;
937 /* Decode the address operand for e.g.
938 LD1 {<Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>}, [<Xn|SP>], <Xm|#<amount>>. */
940 aarch64_ext_simd_addr_post (const aarch64_operand *self ATTRIBUTE_UNUSED,
941 aarch64_opnd_info *info,
942 aarch64_insn code, const aarch64_inst *inst)
944 /* The opcode dependent area stores the number of elements in
945 each structure to be loaded/stored. */
946 int is_ld1r = get_opcode_dependent_value (inst->opcode) == 1;
949 info->addr.base_regno = extract_field (FLD_Rn, code, 0);
951 info->addr.offset.regno = extract_field (FLD_Rm, code, 0);
952 if (info->addr.offset.regno == 31)
954 if (inst->opcode->operands[0] == AARCH64_OPND_LVt_AL)
955 /* Special handling of loading single structure to all lane. */
956 info->addr.offset.imm = (is_ld1r ? 1
957 : inst->operands[0].reglist.num_regs)
958 * aarch64_get_qualifier_esize (inst->operands[0].qualifier);
960 info->addr.offset.imm = inst->operands[0].reglist.num_regs
961 * aarch64_get_qualifier_esize (inst->operands[0].qualifier)
962 * aarch64_get_qualifier_nelem (inst->operands[0].qualifier);
965 info->addr.offset.is_reg = 1;
966 info->addr.writeback = 1;
971 /* Decode the condition operand for e.g. CSEL <Xd>, <Xn>, <Xm>, <cond>. */
973 aarch64_ext_cond (const aarch64_operand *self ATTRIBUTE_UNUSED,
974 aarch64_opnd_info *info,
975 aarch64_insn code, const aarch64_inst *inst ATTRIBUTE_UNUSED)
979 value = extract_field (FLD_cond, code, 0);
980 info->cond = get_cond_from_value (value);
984 /* Decode the system register operand for e.g. MRS <Xt>, <systemreg>. */
986 aarch64_ext_sysreg (const aarch64_operand *self ATTRIBUTE_UNUSED,
987 aarch64_opnd_info *info,
989 const aarch64_inst *inst ATTRIBUTE_UNUSED)
991 /* op0:op1:CRn:CRm:op2 */
992 info->sysreg = extract_fields (code, 0, 5, FLD_op0, FLD_op1, FLD_CRn,
997 /* Decode the PSTATE field operand for e.g. MSR <pstatefield>, #<imm>. */
999 aarch64_ext_pstatefield (const aarch64_operand *self ATTRIBUTE_UNUSED,
1000 aarch64_opnd_info *info, aarch64_insn code,
1001 const aarch64_inst *inst ATTRIBUTE_UNUSED)
1005 info->pstatefield = extract_fields (code, 0, 2, FLD_op1, FLD_op2);
1006 for (i = 0; aarch64_pstatefields[i].name != NULL; ++i)
1007 if (aarch64_pstatefields[i].value == (aarch64_insn)info->pstatefield)
1009 /* Reserved value in <pstatefield>. */
1013 /* Decode the system instruction op operand for e.g. AT <at_op>, <Xt>. */
1015 aarch64_ext_sysins_op (const aarch64_operand *self ATTRIBUTE_UNUSED,
1016 aarch64_opnd_info *info,
1018 const aarch64_inst *inst ATTRIBUTE_UNUSED)
1022 const aarch64_sys_ins_reg *sysins_ops;
1023 /* op0:op1:CRn:CRm:op2 */
1024 value = extract_fields (code, 0, 5,
1025 FLD_op0, FLD_op1, FLD_CRn,
1030 case AARCH64_OPND_SYSREG_AT: sysins_ops = aarch64_sys_regs_at; break;
1031 case AARCH64_OPND_SYSREG_DC: sysins_ops = aarch64_sys_regs_dc; break;
1032 case AARCH64_OPND_SYSREG_IC: sysins_ops = aarch64_sys_regs_ic; break;
1033 case AARCH64_OPND_SYSREG_TLBI: sysins_ops = aarch64_sys_regs_tlbi; break;
1034 default: assert (0); return 0;
1037 for (i = 0; sysins_ops[i].name != NULL; ++i)
1038 if (sysins_ops[i].value == value)
1040 info->sysins_op = sysins_ops + i;
1041 DEBUG_TRACE ("%s found value: %x, has_xt: %d, i: %d.",
1042 info->sysins_op->name,
1043 (unsigned)info->sysins_op->value,
1044 aarch64_sys_ins_reg_has_xt (info->sysins_op), i);
1051 /* Decode the memory barrier option operand for e.g. DMB <option>|#<imm>. */
1054 aarch64_ext_barrier (const aarch64_operand *self ATTRIBUTE_UNUSED,
1055 aarch64_opnd_info *info,
1057 const aarch64_inst *inst ATTRIBUTE_UNUSED)
1060 info->barrier = aarch64_barrier_options + extract_field (FLD_CRm, code, 0);
1064 /* Decode the prefetch operation option operand for e.g.
1065 PRFM <prfop>, [<Xn|SP>{, #<pimm>}]. */
1068 aarch64_ext_prfop (const aarch64_operand *self ATTRIBUTE_UNUSED,
1069 aarch64_opnd_info *info,
1070 aarch64_insn code, const aarch64_inst *inst ATTRIBUTE_UNUSED)
1073 info->prfop = aarch64_prfops + extract_field (FLD_Rt, code, 0);
1077 /* Decode the hint number for an alias taking an operand. Set info->hint_option
1078 to the matching name/value pair in aarch64_hint_options. */
1081 aarch64_ext_hint (const aarch64_operand *self ATTRIBUTE_UNUSED,
1082 aarch64_opnd_info *info,
1084 const aarch64_inst *inst ATTRIBUTE_UNUSED)
1087 unsigned hint_number;
1090 hint_number = extract_fields (code, 0, 2, FLD_CRm, FLD_op2);
1092 for (i = 0; aarch64_hint_options[i].name != NULL; i++)
1094 if (hint_number == aarch64_hint_options[i].value)
1096 info->hint_option = &(aarch64_hint_options[i]);
1104 /* Decode the extended register operand for e.g.
1105 STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]. */
1107 aarch64_ext_reg_extended (const aarch64_operand *self ATTRIBUTE_UNUSED,
1108 aarch64_opnd_info *info,
1110 const aarch64_inst *inst ATTRIBUTE_UNUSED)
1115 info->reg.regno = extract_field (FLD_Rm, code, 0);
1117 value = extract_field (FLD_option, code, 0);
1118 info->shifter.kind =
1119 aarch64_get_operand_modifier_from_value (value, TRUE /* extend_p */);
1121 info->shifter.amount = extract_field (FLD_imm3, code, 0);
1123 /* This makes the constraint checking happy. */
1124 info->shifter.operator_present = 1;
1126 /* Assume inst->operands[0].qualifier has been resolved. */
1127 assert (inst->operands[0].qualifier != AARCH64_OPND_QLF_NIL);
1128 info->qualifier = AARCH64_OPND_QLF_W;
1129 if (inst->operands[0].qualifier == AARCH64_OPND_QLF_X
1130 && (info->shifter.kind == AARCH64_MOD_UXTX
1131 || info->shifter.kind == AARCH64_MOD_SXTX))
1132 info->qualifier = AARCH64_OPND_QLF_X;
1137 /* Decode the shifted register operand for e.g.
1138 SUBS <Xd>, <Xn>, <Xm> {, <shift> #<amount>}. */
1140 aarch64_ext_reg_shifted (const aarch64_operand *self ATTRIBUTE_UNUSED,
1141 aarch64_opnd_info *info,
1143 const aarch64_inst *inst ATTRIBUTE_UNUSED)
1148 info->reg.regno = extract_field (FLD_Rm, code, 0);
1150 value = extract_field (FLD_shift, code, 0);
1151 info->shifter.kind =
1152 aarch64_get_operand_modifier_from_value (value, FALSE /* extend_p */);
1153 if (info->shifter.kind == AARCH64_MOD_ROR
1154 && inst->opcode->iclass != log_shift)
1155 /* ROR is not available for the shifted register operand in arithmetic
1159 info->shifter.amount = extract_field (FLD_imm6, code, 0);
1161 /* This makes the constraint checking happy. */
1162 info->shifter.operator_present = 1;
1167 /* Bitfields that are commonly used to encode certain operands' information
1168 may be partially used as part of the base opcode in some instructions.
1169 For example, the bit 1 of the field 'size' in
1170 FCVTXN <Vb><d>, <Va><n>
1171 is actually part of the base opcode, while only size<0> is available
1172 for encoding the register type. Another example is the AdvSIMD
1173 instruction ORR (register), in which the field 'size' is also used for
1174 the base opcode, leaving only the field 'Q' available to encode the
1175 vector register arrangement specifier '8B' or '16B'.
1177 This function tries to deduce the qualifier from the value of partially
1178 constrained field(s). Given the VALUE of such a field or fields, the
1179 qualifiers CANDIDATES and the MASK (indicating which bits are valid for
1180 operand encoding), the function returns the matching qualifier or
1181 AARCH64_OPND_QLF_NIL if nothing matches.
1183 N.B. CANDIDATES is a group of possible qualifiers that are valid for
1184 one operand; it has a maximum of AARCH64_MAX_QLF_SEQ_NUM qualifiers and
1185 may end with AARCH64_OPND_QLF_NIL. */
1187 static enum aarch64_opnd_qualifier
1188 get_qualifier_from_partial_encoding (aarch64_insn value,
1189 const enum aarch64_opnd_qualifier* \
1194 DEBUG_TRACE ("enter with value: %d, mask: %d", (int)value, (int)mask);
1195 for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
1197 aarch64_insn standard_value;
1198 if (candidates[i] == AARCH64_OPND_QLF_NIL)
1200 standard_value = aarch64_get_qualifier_standard_value (candidates[i]);
1201 if ((standard_value & mask) == (value & mask))
1202 return candidates[i];
1204 return AARCH64_OPND_QLF_NIL;
1207 /* Given a list of qualifier sequences, return all possible valid qualifiers
1208 for operand IDX in QUALIFIERS.
1209 Assume QUALIFIERS is an array whose length is large enough. */
1212 get_operand_possible_qualifiers (int idx,
1213 const aarch64_opnd_qualifier_seq_t *list,
1214 enum aarch64_opnd_qualifier *qualifiers)
1217 for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
1218 if ((qualifiers[i] = list[i][idx]) == AARCH64_OPND_QLF_NIL)
1222 /* Decode the size Q field for e.g. SHADD.
1223 We tag one operand with the qualifer according to the code;
1224 whether the qualifier is valid for this opcode or not, it is the
1225 duty of the semantic checking. */
1228 decode_sizeq (aarch64_inst *inst)
1231 enum aarch64_opnd_qualifier qualifier;
1233 aarch64_insn value, mask;
1234 enum aarch64_field_kind fld_sz;
1235 enum aarch64_opnd_qualifier candidates[AARCH64_MAX_QLF_SEQ_NUM];
1237 if (inst->opcode->iclass == asisdlse
1238 || inst->opcode->iclass == asisdlsep
1239 || inst->opcode->iclass == asisdlso
1240 || inst->opcode->iclass == asisdlsop)
1241 fld_sz = FLD_vldst_size;
1246 value = extract_fields (code, inst->opcode->mask, 2, fld_sz, FLD_Q);
1247 /* Obtain the info that which bits of fields Q and size are actually
1248 available for operand encoding. Opcodes like FMAXNM and FMLA have
1249 size[1] unavailable. */
1250 mask = extract_fields (~inst->opcode->mask, 0, 2, fld_sz, FLD_Q);
1252 /* The index of the operand we are going to tag a qualifier and the qualifer
1253 itself are reasoned from the value of the size and Q fields and the
1254 possible valid qualifier lists. */
1255 idx = aarch64_select_operand_for_sizeq_field_coding (inst->opcode);
1256 DEBUG_TRACE ("key idx: %d", idx);
1258 /* For most related instruciton, size:Q are fully available for operand
1262 inst->operands[idx].qualifier = get_vreg_qualifier_from_value (value);
1266 get_operand_possible_qualifiers (idx, inst->opcode->qualifiers_list,
1268 #ifdef DEBUG_AARCH64
1272 for (i = 0; candidates[i] != AARCH64_OPND_QLF_NIL
1273 && i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
1274 DEBUG_TRACE ("qualifier %d: %s", i,
1275 aarch64_get_qualifier_name(candidates[i]));
1276 DEBUG_TRACE ("%d, %d", (int)value, (int)mask);
1278 #endif /* DEBUG_AARCH64 */
1280 qualifier = get_qualifier_from_partial_encoding (value, candidates, mask);
1282 if (qualifier == AARCH64_OPND_QLF_NIL)
1285 inst->operands[idx].qualifier = qualifier;
1289 /* Decode size[0]:Q, i.e. bit 22 and bit 30, for
1290 e.g. FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>. */
1293 decode_asimd_fcvt (aarch64_inst *inst)
1295 aarch64_field field = {0, 0};
1297 enum aarch64_opnd_qualifier qualifier;
1299 gen_sub_field (FLD_size, 0, 1, &field);
1300 value = extract_field_2 (&field, inst->value, 0);
1301 qualifier = value == 0 ? AARCH64_OPND_QLF_V_4S
1302 : AARCH64_OPND_QLF_V_2D;
1303 switch (inst->opcode->op)
1307 /* FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>. */
1308 inst->operands[1].qualifier = qualifier;
1312 /* FCVTL<Q> <Vd>.<Ta>, <Vn>.<Tb>. */
1313 inst->operands[0].qualifier = qualifier;
1323 /* Decode size[0], i.e. bit 22, for
1324 e.g. FCVTXN <Vb><d>, <Va><n>. */
1327 decode_asisd_fcvtxn (aarch64_inst *inst)
1329 aarch64_field field = {0, 0};
1330 gen_sub_field (FLD_size, 0, 1, &field);
1331 if (!extract_field_2 (&field, inst->value, 0))
1333 inst->operands[0].qualifier = AARCH64_OPND_QLF_S_S;
1337 /* Decode the 'opc' field for e.g. FCVT <Dd>, <Sn>. */
1339 decode_fcvt (aarch64_inst *inst)
1341 enum aarch64_opnd_qualifier qualifier;
1343 const aarch64_field field = {15, 2};
1346 value = extract_field_2 (&field, inst->value, 0);
1349 case 0: qualifier = AARCH64_OPND_QLF_S_S; break;
1350 case 1: qualifier = AARCH64_OPND_QLF_S_D; break;
1351 case 3: qualifier = AARCH64_OPND_QLF_S_H; break;
1354 inst->operands[0].qualifier = qualifier;
1359 /* Do miscellaneous decodings that are not common enough to be driven by
1363 do_misc_decoding (aarch64_inst *inst)
1365 switch (inst->opcode->op)
1368 return decode_fcvt (inst);
1373 return decode_asimd_fcvt (inst);
1375 return decode_asisd_fcvtxn (inst);
1381 /* Opcodes that have fields shared by multiple operands are usually flagged
1382 with flags. In this function, we detect such flags, decode the related
1383 field(s) and store the information in one of the related operands. The
1384 'one' operand is not any operand but one of the operands that can
1385 accommadate all the information that has been decoded. */
1388 do_special_decoding (aarch64_inst *inst)
1392 /* Condition for truly conditional executed instructions, e.g. b.cond. */
1393 if (inst->opcode->flags & F_COND)
1395 value = extract_field (FLD_cond2, inst->value, 0);
1396 inst->cond = get_cond_from_value (value);
1399 if (inst->opcode->flags & F_SF)
1401 idx = select_operand_for_sf_field_coding (inst->opcode);
1402 value = extract_field (FLD_sf, inst->value, 0);
1403 inst->operands[idx].qualifier = get_greg_qualifier_from_value (value);
1404 if ((inst->opcode->flags & F_N)
1405 && extract_field (FLD_N, inst->value, 0) != value)
1409 if (inst->opcode->flags & F_LSE_SZ)
1411 idx = select_operand_for_sf_field_coding (inst->opcode);
1412 value = extract_field (FLD_lse_sz, inst->value, 0);
1413 inst->operands[idx].qualifier = get_greg_qualifier_from_value (value);
1415 /* size:Q fields. */
1416 if (inst->opcode->flags & F_SIZEQ)
1417 return decode_sizeq (inst);
1419 if (inst->opcode->flags & F_FPTYPE)
1421 idx = select_operand_for_fptype_field_coding (inst->opcode);
1422 value = extract_field (FLD_type, inst->value, 0);
1425 case 0: inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_S; break;
1426 case 1: inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_D; break;
1427 case 3: inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_H; break;
1432 if (inst->opcode->flags & F_SSIZE)
1434 /* N.B. some opcodes like FCMGT <V><d>, <V><n>, #0 have the size[1] as part
1435 of the base opcode. */
1437 enum aarch64_opnd_qualifier candidates[AARCH64_MAX_QLF_SEQ_NUM];
1438 idx = select_operand_for_scalar_size_field_coding (inst->opcode);
1439 value = extract_field (FLD_size, inst->value, inst->opcode->mask);
1440 mask = extract_field (FLD_size, ~inst->opcode->mask, 0);
1441 /* For most related instruciton, the 'size' field is fully available for
1442 operand encoding. */
1444 inst->operands[idx].qualifier = get_sreg_qualifier_from_value (value);
1447 get_operand_possible_qualifiers (idx, inst->opcode->qualifiers_list,
1449 inst->operands[idx].qualifier
1450 = get_qualifier_from_partial_encoding (value, candidates, mask);
1454 if (inst->opcode->flags & F_T)
1456 /* Num of consecutive '0's on the right side of imm5<3:0>. */
1459 assert (aarch64_get_operand_class (inst->opcode->operands[0])
1460 == AARCH64_OPND_CLASS_SIMD_REG);
1471 val = extract_field (FLD_imm5, inst->value, 0);
1472 while ((val & 0x1) == 0 && ++num <= 3)
1476 Q = (unsigned) extract_field (FLD_Q, inst->value, inst->opcode->mask);
1477 inst->operands[0].qualifier =
1478 get_vreg_qualifier_from_value ((num << 1) | Q);
1481 if (inst->opcode->flags & F_GPRSIZE_IN_Q)
1483 /* Use Rt to encode in the case of e.g.
1484 STXP <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}]. */
1485 idx = aarch64_operand_index (inst->opcode->operands, AARCH64_OPND_Rt);
1488 /* Otherwise use the result operand, which has to be a integer
1490 assert (aarch64_get_operand_class (inst->opcode->operands[0])
1491 == AARCH64_OPND_CLASS_INT_REG);
1494 assert (idx == 0 || idx == 1);
1495 value = extract_field (FLD_Q, inst->value, 0);
1496 inst->operands[idx].qualifier = get_greg_qualifier_from_value (value);
1499 if (inst->opcode->flags & F_LDS_SIZE)
1501 aarch64_field field = {0, 0};
1502 assert (aarch64_get_operand_class (inst->opcode->operands[0])
1503 == AARCH64_OPND_CLASS_INT_REG);
1504 gen_sub_field (FLD_opc, 0, 1, &field);
1505 value = extract_field_2 (&field, inst->value, 0);
1506 inst->operands[0].qualifier
1507 = value ? AARCH64_OPND_QLF_W : AARCH64_OPND_QLF_X;
1510 /* Miscellaneous decoding; done as the last step. */
1511 if (inst->opcode->flags & F_MISC)
1512 return do_misc_decoding (inst);
1517 /* Converters converting a real opcode instruction to its alias form. */
1519 /* ROR <Wd>, <Ws>, #<shift>
1521 EXTR <Wd>, <Ws>, <Ws>, #<shift>. */
1523 convert_extr_to_ror (aarch64_inst *inst)
1525 if (inst->operands[1].reg.regno == inst->operands[2].reg.regno)
1527 copy_operand_info (inst, 2, 3);
1528 inst->operands[3].type = AARCH64_OPND_NIL;
1534 /* UXTL<Q> <Vd>.<Ta>, <Vn>.<Tb>
1536 USHLL<Q> <Vd>.<Ta>, <Vn>.<Tb>, #0. */
1538 convert_shll_to_xtl (aarch64_inst *inst)
1540 if (inst->operands[2].imm.value == 0)
1542 inst->operands[2].type = AARCH64_OPND_NIL;
1549 UBFM <Xd>, <Xn>, #<shift>, #63.
1551 LSR <Xd>, <Xn>, #<shift>. */
1553 convert_bfm_to_sr (aarch64_inst *inst)
1557 imms = inst->operands[3].imm.value;
1558 val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 31 : 63;
1561 inst->operands[3].type = AARCH64_OPND_NIL;
1568 /* Convert MOV to ORR. */
1570 convert_orr_to_mov (aarch64_inst *inst)
1572 /* MOV <Vd>.<T>, <Vn>.<T>
1574 ORR <Vd>.<T>, <Vn>.<T>, <Vn>.<T>. */
1575 if (inst->operands[1].reg.regno == inst->operands[2].reg.regno)
1577 inst->operands[2].type = AARCH64_OPND_NIL;
1583 /* When <imms> >= <immr>, the instruction written:
1584 SBFX <Xd>, <Xn>, #<lsb>, #<width>
1586 SBFM <Xd>, <Xn>, #<lsb>, #(<lsb>+<width>-1). */
1589 convert_bfm_to_bfx (aarch64_inst *inst)
1593 immr = inst->operands[2].imm.value;
1594 imms = inst->operands[3].imm.value;
1598 inst->operands[2].imm.value = lsb;
1599 inst->operands[3].imm.value = imms + 1 - lsb;
1600 /* The two opcodes have different qualifiers for
1601 the immediate operands; reset to help the checking. */
1602 reset_operand_qualifier (inst, 2);
1603 reset_operand_qualifier (inst, 3);
1610 /* When <imms> < <immr>, the instruction written:
1611 SBFIZ <Xd>, <Xn>, #<lsb>, #<width>
1613 SBFM <Xd>, <Xn>, #((64-<lsb>)&0x3f), #(<width>-1). */
1616 convert_bfm_to_bfi (aarch64_inst *inst)
1618 int64_t immr, imms, val;
1620 immr = inst->operands[2].imm.value;
1621 imms = inst->operands[3].imm.value;
1622 val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 32 : 64;
1625 inst->operands[2].imm.value = (val - immr) & (val - 1);
1626 inst->operands[3].imm.value = imms + 1;
1627 /* The two opcodes have different qualifiers for
1628 the immediate operands; reset to help the checking. */
1629 reset_operand_qualifier (inst, 2);
1630 reset_operand_qualifier (inst, 3);
1637 /* The instruction written:
1638 BFC <Xd>, #<lsb>, #<width>
1640 BFM <Xd>, XZR, #((64-<lsb>)&0x3f), #(<width>-1). */
1643 convert_bfm_to_bfc (aarch64_inst *inst)
1645 int64_t immr, imms, val;
1647 /* Should have been assured by the base opcode value. */
1648 assert (inst->operands[1].reg.regno == 0x1f);
1650 immr = inst->operands[2].imm.value;
1651 imms = inst->operands[3].imm.value;
1652 val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 32 : 64;
1655 /* Drop XZR from the second operand. */
1656 copy_operand_info (inst, 1, 2);
1657 copy_operand_info (inst, 2, 3);
1658 inst->operands[3].type = AARCH64_OPND_NIL;
1660 /* Recalculate the immediates. */
1661 inst->operands[1].imm.value = (val - immr) & (val - 1);
1662 inst->operands[2].imm.value = imms + 1;
1664 /* The two opcodes have different qualifiers for the operands; reset to
1665 help the checking. */
1666 reset_operand_qualifier (inst, 1);
1667 reset_operand_qualifier (inst, 2);
1668 reset_operand_qualifier (inst, 3);
1676 /* The instruction written:
1677 LSL <Xd>, <Xn>, #<shift>
1679 UBFM <Xd>, <Xn>, #((64-<shift>)&0x3f), #(63-<shift>). */
1682 convert_ubfm_to_lsl (aarch64_inst *inst)
1684 int64_t immr = inst->operands[2].imm.value;
1685 int64_t imms = inst->operands[3].imm.value;
1687 = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 31 : 63;
1689 if ((immr == 0 && imms == val) || immr == imms + 1)
1691 inst->operands[3].type = AARCH64_OPND_NIL;
1692 inst->operands[2].imm.value = val - imms;
1699 /* CINC <Wd>, <Wn>, <cond>
1701 CSINC <Wd>, <Wn>, <Wn>, invert(<cond>)
1702 where <cond> is not AL or NV. */
1705 convert_from_csel (aarch64_inst *inst)
1707 if (inst->operands[1].reg.regno == inst->operands[2].reg.regno
1708 && (inst->operands[3].cond->value & 0xe) != 0xe)
1710 copy_operand_info (inst, 2, 3);
1711 inst->operands[2].cond = get_inverted_cond (inst->operands[3].cond);
1712 inst->operands[3].type = AARCH64_OPND_NIL;
1718 /* CSET <Wd>, <cond>
1720 CSINC <Wd>, WZR, WZR, invert(<cond>)
1721 where <cond> is not AL or NV. */
1724 convert_csinc_to_cset (aarch64_inst *inst)
1726 if (inst->operands[1].reg.regno == 0x1f
1727 && inst->operands[2].reg.regno == 0x1f
1728 && (inst->operands[3].cond->value & 0xe) != 0xe)
1730 copy_operand_info (inst, 1, 3);
1731 inst->operands[1].cond = get_inverted_cond (inst->operands[3].cond);
1732 inst->operands[3].type = AARCH64_OPND_NIL;
1733 inst->operands[2].type = AARCH64_OPND_NIL;
1741 MOVZ <Wd>, #<imm16>, LSL #<shift>.
1743 A disassembler may output ORR, MOVZ and MOVN as a MOV mnemonic, except when
1744 ORR has an immediate that could be generated by a MOVZ or MOVN instruction,
1745 or where a MOVN has an immediate that could be encoded by MOVZ, or where
1746 MOVZ/MOVN #0 have a shift amount other than LSL #0, in which case the
1747 machine-instruction mnemonic must be used. */
1750 convert_movewide_to_mov (aarch64_inst *inst)
1752 uint64_t value = inst->operands[1].imm.value;
1753 /* MOVZ/MOVN #0 have a shift amount other than LSL #0. */
1754 if (value == 0 && inst->operands[1].shifter.amount != 0)
1756 inst->operands[1].type = AARCH64_OPND_IMM_MOV;
1757 inst->operands[1].shifter.kind = AARCH64_MOD_NONE;
1758 value <<= inst->operands[1].shifter.amount;
1759 /* As an alias convertor, it has to be clear that the INST->OPCODE
1760 is the opcode of the real instruction. */
1761 if (inst->opcode->op == OP_MOVN)
1763 int is32 = inst->operands[0].qualifier == AARCH64_OPND_QLF_W;
1765 /* A MOVN has an immediate that could be encoded by MOVZ. */
1766 if (aarch64_wide_constant_p (value, is32, NULL) == TRUE)
1769 inst->operands[1].imm.value = value;
1770 inst->operands[1].shifter.amount = 0;
1776 ORR <Wd>, WZR, #<imm>.
1778 A disassembler may output ORR, MOVZ and MOVN as a MOV mnemonic, except when
1779 ORR has an immediate that could be generated by a MOVZ or MOVN instruction,
1780 or where a MOVN has an immediate that could be encoded by MOVZ, or where
1781 MOVZ/MOVN #0 have a shift amount other than LSL #0, in which case the
1782 machine-instruction mnemonic must be used. */
1785 convert_movebitmask_to_mov (aarch64_inst *inst)
1790 /* Should have been assured by the base opcode value. */
1791 assert (inst->operands[1].reg.regno == 0x1f);
1792 copy_operand_info (inst, 1, 2);
1793 is32 = inst->operands[0].qualifier == AARCH64_OPND_QLF_W;
1794 inst->operands[1].type = AARCH64_OPND_IMM_MOV;
1795 value = inst->operands[1].imm.value;
1796 /* ORR has an immediate that could be generated by a MOVZ or MOVN
1798 if (inst->operands[0].reg.regno != 0x1f
1799 && (aarch64_wide_constant_p (value, is32, NULL) == TRUE
1800 || aarch64_wide_constant_p (~value, is32, NULL) == TRUE))
1803 inst->operands[2].type = AARCH64_OPND_NIL;
1807 /* Some alias opcodes are disassembled by being converted from their real-form.
1808 N.B. INST->OPCODE is the real opcode rather than the alias. */
1811 convert_to_alias (aarch64_inst *inst, const aarch64_opcode *alias)
1817 return convert_bfm_to_sr (inst);
1819 return convert_ubfm_to_lsl (inst);
1823 return convert_from_csel (inst);
1826 return convert_csinc_to_cset (inst);
1830 return convert_bfm_to_bfx (inst);
1834 return convert_bfm_to_bfi (inst);
1836 return convert_bfm_to_bfc (inst);
1838 return convert_orr_to_mov (inst);
1839 case OP_MOV_IMM_WIDE:
1840 case OP_MOV_IMM_WIDEN:
1841 return convert_movewide_to_mov (inst);
1842 case OP_MOV_IMM_LOG:
1843 return convert_movebitmask_to_mov (inst);
1845 return convert_extr_to_ror (inst);
1850 return convert_shll_to_xtl (inst);
1856 static int aarch64_opcode_decode (const aarch64_opcode *, const aarch64_insn,
1857 aarch64_inst *, int);
1859 /* Given the instruction information in *INST, check if the instruction has
1860 any alias form that can be used to represent *INST. If the answer is yes,
1861 update *INST to be in the form of the determined alias. */
1863 /* In the opcode description table, the following flags are used in opcode
1864 entries to help establish the relations between the real and alias opcodes:
1866 F_ALIAS: opcode is an alias
1867 F_HAS_ALIAS: opcode has alias(es)
1870 F_P3: Disassembly preference priority 1-3 (the larger the
1871 higher). If nothing is specified, it is the priority
1872 0 by default, i.e. the lowest priority.
1874 Although the relation between the machine and the alias instructions are not
1875 explicitly described, it can be easily determined from the base opcode
1876 values, masks and the flags F_ALIAS and F_HAS_ALIAS in their opcode
1877 description entries:
1879 The mask of an alias opcode must be equal to or a super-set (i.e. more
1880 constrained) of that of the aliased opcode; so is the base opcode value.
1882 if (opcode_has_alias (real) && alias_opcode_p (opcode)
1883 && (opcode->mask & real->mask) == real->mask
1884 && (real->mask & opcode->opcode) == (real->mask & real->opcode))
1885 then OPCODE is an alias of, and only of, the REAL instruction
1887 The alias relationship is forced flat-structured to keep related algorithm
1888 simple; an opcode entry cannot be flagged with both F_ALIAS and F_HAS_ALIAS.
1890 During the disassembling, the decoding decision tree (in
1891 opcodes/aarch64-dis-2.c) always returns an machine instruction opcode entry;
1892 if the decoding of such a machine instruction succeeds (and -Mno-aliases is
1893 not specified), the disassembler will check whether there is any alias
1894 instruction exists for this real instruction. If there is, the disassembler
1895 will try to disassemble the 32-bit binary again using the alias's rule, or
1896 try to convert the IR to the form of the alias. In the case of the multiple
1897 aliases, the aliases are tried one by one from the highest priority
1898 (currently the flag F_P3) to the lowest priority (no priority flag), and the
1899 first succeeds first adopted.
1901 You may ask why there is a need for the conversion of IR from one form to
1902 another in handling certain aliases. This is because on one hand it avoids
1903 adding more operand code to handle unusual encoding/decoding; on other
1904 hand, during the disassembling, the conversion is an effective approach to
1905 check the condition of an alias (as an alias may be adopted only if certain
1906 conditions are met).
1908 In order to speed up the alias opcode lookup, aarch64-gen has preprocessed
1909 aarch64_opcode_table and generated aarch64_find_alias_opcode and
1910 aarch64_find_next_alias_opcode (in opcodes/aarch64-dis-2.c) to help. */
1913 determine_disassembling_preference (struct aarch64_inst *inst)
1915 const aarch64_opcode *opcode;
1916 const aarch64_opcode *alias;
1918 opcode = inst->opcode;
1920 /* This opcode does not have an alias, so use itself. */
1921 if (opcode_has_alias (opcode) == FALSE)
1924 alias = aarch64_find_alias_opcode (opcode);
1927 #ifdef DEBUG_AARCH64
1930 const aarch64_opcode *tmp = alias;
1931 printf ("#### LIST orderd: ");
1934 printf ("%s, ", tmp->name);
1935 tmp = aarch64_find_next_alias_opcode (tmp);
1939 #endif /* DEBUG_AARCH64 */
1941 for (; alias; alias = aarch64_find_next_alias_opcode (alias))
1943 DEBUG_TRACE ("try %s", alias->name);
1944 assert (alias_opcode_p (alias) || opcode_has_alias (opcode));
1946 /* An alias can be a pseudo opcode which will never be used in the
1947 disassembly, e.g. BIC logical immediate is such a pseudo opcode
1949 if (pseudo_opcode_p (alias))
1951 DEBUG_TRACE ("skip pseudo %s", alias->name);
1955 if ((inst->value & alias->mask) != alias->opcode)
1957 DEBUG_TRACE ("skip %s as base opcode not match", alias->name);
1960 /* No need to do any complicated transformation on operands, if the alias
1961 opcode does not have any operand. */
1962 if (aarch64_num_of_operands (alias) == 0 && alias->opcode == inst->value)
1964 DEBUG_TRACE ("succeed with 0-operand opcode %s", alias->name);
1965 aarch64_replace_opcode (inst, alias);
1968 if (alias->flags & F_CONV)
1971 memcpy (©, inst, sizeof (aarch64_inst));
1972 /* ALIAS is the preference as long as the instruction can be
1973 successfully converted to the form of ALIAS. */
1974 if (convert_to_alias (©, alias) == 1)
1976 aarch64_replace_opcode (©, alias);
1977 assert (aarch64_match_operands_constraint (©, NULL));
1978 DEBUG_TRACE ("succeed with %s via conversion", alias->name);
1979 memcpy (inst, ©, sizeof (aarch64_inst));
1985 /* Directly decode the alias opcode. */
1987 memset (&temp, '\0', sizeof (aarch64_inst));
1988 if (aarch64_opcode_decode (alias, inst->value, &temp, 1) == 1)
1990 DEBUG_TRACE ("succeed with %s via direct decoding", alias->name);
1991 memcpy (inst, &temp, sizeof (aarch64_inst));
1998 /* Decode the CODE according to OPCODE; fill INST. Return 0 if the decoding
1999 fails, which meanes that CODE is not an instruction of OPCODE; otherwise
2002 If OPCODE has alias(es) and NOALIASES_P is 0, an alias opcode may be
2003 determined and used to disassemble CODE; this is done just before the
2007 aarch64_opcode_decode (const aarch64_opcode *opcode, const aarch64_insn code,
2008 aarch64_inst *inst, int noaliases_p)
2012 DEBUG_TRACE ("enter with %s", opcode->name);
2014 assert (opcode && inst);
2016 /* Check the base opcode. */
2017 if ((code & opcode->mask) != (opcode->opcode & opcode->mask))
2019 DEBUG_TRACE ("base opcode match FAIL");
2024 memset (inst, '\0', sizeof (aarch64_inst));
2026 inst->opcode = opcode;
2029 /* Assign operand codes and indexes. */
2030 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2032 if (opcode->operands[i] == AARCH64_OPND_NIL)
2034 inst->operands[i].type = opcode->operands[i];
2035 inst->operands[i].idx = i;
2038 /* Call the opcode decoder indicated by flags. */
2039 if (opcode_has_special_coder (opcode) && do_special_decoding (inst) == 0)
2041 DEBUG_TRACE ("opcode flag-based decoder FAIL");
2045 /* Call operand decoders. */
2046 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2048 const aarch64_operand *opnd;
2049 enum aarch64_opnd type;
2050 type = opcode->operands[i];
2051 if (type == AARCH64_OPND_NIL)
2053 opnd = &aarch64_operands[type];
2054 if (operand_has_extractor (opnd)
2055 && (! aarch64_extract_operand (opnd, &inst->operands[i], code, inst)))
2057 DEBUG_TRACE ("operand decoder FAIL at operand %d", i);
2062 /* Match the qualifiers. */
2063 if (aarch64_match_operands_constraint (inst, NULL) == 1)
2065 /* Arriving here, the CODE has been determined as a valid instruction
2066 of OPCODE and *INST has been filled with information of this OPCODE
2067 instruction. Before the return, check if the instruction has any
2068 alias and should be disassembled in the form of its alias instead.
2069 If the answer is yes, *INST will be updated. */
2071 determine_disassembling_preference (inst);
2072 DEBUG_TRACE ("SUCCESS");
2077 DEBUG_TRACE ("constraint matching FAIL");
2084 /* This does some user-friendly fix-up to *INST. It is currently focus on
2085 the adjustment of qualifiers to help the printed instruction
2086 recognized/understood more easily. */
2089 user_friendly_fixup (aarch64_inst *inst)
2091 switch (inst->opcode->iclass)
2094 /* TBNZ Xn|Wn, #uimm6, label
2095 Test and Branch Not Zero: conditionally jumps to label if bit number
2096 uimm6 in register Xn is not zero. The bit number implies the width of
2097 the register, which may be written and should be disassembled as Wn if
2098 uimm is less than 32. Limited to a branch offset range of +/- 32KiB.
2100 if (inst->operands[1].imm.value < 32)
2101 inst->operands[0].qualifier = AARCH64_OPND_QLF_W;
2107 /* Decode INSN and fill in *INST the instruction information. An alias
2108 opcode may be filled in *INSN if NOALIASES_P is FALSE. Return zero on
2112 aarch64_decode_insn (aarch64_insn insn, aarch64_inst *inst,
2113 bfd_boolean noaliases_p)
2115 const aarch64_opcode *opcode = aarch64_opcode_lookup (insn);
2117 #ifdef DEBUG_AARCH64
2120 const aarch64_opcode *tmp = opcode;
2122 DEBUG_TRACE ("opcode lookup:");
2125 aarch64_verbose (" %s", tmp->name);
2126 tmp = aarch64_find_next_opcode (tmp);
2129 #endif /* DEBUG_AARCH64 */
2131 /* A list of opcodes may have been found, as aarch64_opcode_lookup cannot
2132 distinguish some opcodes, e.g. SSHR and MOVI, which almost share the same
2133 opcode field and value, apart from the difference that one of them has an
2134 extra field as part of the opcode, but such a field is used for operand
2135 encoding in other opcode(s) ('immh' in the case of the example). */
2136 while (opcode != NULL)
2138 /* But only one opcode can be decoded successfully for, as the
2139 decoding routine will check the constraint carefully. */
2140 if (aarch64_opcode_decode (opcode, insn, inst, noaliases_p) == 1)
2142 opcode = aarch64_find_next_opcode (opcode);
2148 /* Print operands. */
2151 print_operands (bfd_vma pc, const aarch64_opcode *opcode,
2152 const aarch64_opnd_info *opnds, struct disassemble_info *info)
2154 int i, pcrel_p, num_printed;
2155 for (i = 0, num_printed = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2158 /* We regard the opcode operand info more, however we also look into
2159 the inst->operands to support the disassembling of the optional
2161 The two operand code should be the same in all cases, apart from
2162 when the operand can be optional. */
2163 if (opcode->operands[i] == AARCH64_OPND_NIL
2164 || opnds[i].type == AARCH64_OPND_NIL)
2167 /* Generate the operand string in STR. */
2168 aarch64_print_operand (str, sizeof (str), pc, opcode, opnds, i, &pcrel_p,
2171 /* Print the delimiter (taking account of omitted operand(s)). */
2173 (*info->fprintf_func) (info->stream, "%s",
2174 num_printed++ == 0 ? "\t" : ", ");
2176 /* Print the operand. */
2178 (*info->print_address_func) (info->target, info);
2180 (*info->fprintf_func) (info->stream, "%s", str);
2184 /* Print the instruction mnemonic name. */
2187 print_mnemonic_name (const aarch64_inst *inst, struct disassemble_info *info)
2189 if (inst->opcode->flags & F_COND)
2191 /* For instructions that are truly conditionally executed, e.g. b.cond,
2192 prepare the full mnemonic name with the corresponding condition
2197 ptr = strchr (inst->opcode->name, '.');
2198 assert (ptr && inst->cond);
2199 len = ptr - inst->opcode->name;
2201 strncpy (name, inst->opcode->name, len);
2203 (*info->fprintf_func) (info->stream, "%s.%s", name, inst->cond->names[0]);
2206 (*info->fprintf_func) (info->stream, "%s", inst->opcode->name);
2209 /* Print the instruction according to *INST. */
2212 print_aarch64_insn (bfd_vma pc, const aarch64_inst *inst,
2213 struct disassemble_info *info)
2215 print_mnemonic_name (inst, info);
2216 print_operands (pc, inst->opcode, inst->operands, info);
2219 /* Entry-point of the instruction disassembler and printer. */
2222 print_insn_aarch64_word (bfd_vma pc,
2224 struct disassemble_info *info)
2226 static const char *err_msg[6] =
2229 [-ERR_UND] = "undefined",
2230 [-ERR_UNP] = "unpredictable",
2237 info->insn_info_valid = 1;
2238 info->branch_delay_insns = 0;
2239 info->data_size = 0;
2243 if (info->flags & INSN_HAS_RELOC)
2244 /* If the instruction has a reloc associated with it, then
2245 the offset field in the instruction will actually be the
2246 addend for the reloc. (If we are using REL type relocs).
2247 In such cases, we can ignore the pc when computing
2248 addresses, since the addend is not currently pc-relative. */
2251 ret = aarch64_decode_insn (word, &inst, no_aliases);
2253 if (((word >> 21) & 0x3ff) == 1)
2255 /* RESERVED for ALES. */
2256 assert (ret != ERR_OK);
2265 /* Handle undefined instructions. */
2266 info->insn_type = dis_noninsn;
2267 (*info->fprintf_func) (info->stream,".inst\t0x%08x ; %s",
2268 word, err_msg[-ret]);
2271 user_friendly_fixup (&inst);
2272 print_aarch64_insn (pc, &inst, info);
2279 /* Disallow mapping symbols ($x, $d etc) from
2280 being displayed in symbol relative addresses. */
2283 aarch64_symbol_is_valid (asymbol * sym,
2284 struct disassemble_info * info ATTRIBUTE_UNUSED)
2291 name = bfd_asymbol_name (sym);
2295 || (name[1] != 'x' && name[1] != 'd')
2296 || (name[2] != '\0' && name[2] != '.'));
2299 /* Print data bytes on INFO->STREAM. */
2302 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
2304 struct disassemble_info *info)
2306 switch (info->bytes_per_chunk)
2309 info->fprintf_func (info->stream, ".byte\t0x%02x", word);
2312 info->fprintf_func (info->stream, ".short\t0x%04x", word);
2315 info->fprintf_func (info->stream, ".word\t0x%08x", word);
2322 /* Try to infer the code or data type from a symbol.
2323 Returns nonzero if *MAP_TYPE was set. */
2326 get_sym_code_type (struct disassemble_info *info, int n,
2327 enum map_type *map_type)
2329 elf_symbol_type *es;
2333 es = *(elf_symbol_type **)(info->symtab + n);
2334 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
2336 /* If the symbol has function type then use that. */
2337 if (type == STT_FUNC)
2339 *map_type = MAP_INSN;
2343 /* Check for mapping symbols. */
2344 name = bfd_asymbol_name(info->symtab[n]);
2346 && (name[1] == 'x' || name[1] == 'd')
2347 && (name[2] == '\0' || name[2] == '.'))
2349 *map_type = (name[1] == 'x' ? MAP_INSN : MAP_DATA);
2356 /* Entry-point of the AArch64 disassembler. */
2359 print_insn_aarch64 (bfd_vma pc,
2360 struct disassemble_info *info)
2362 bfd_byte buffer[INSNLEN];
2364 void (*printer) (bfd_vma, uint32_t, struct disassemble_info *);
2365 bfd_boolean found = FALSE;
2366 unsigned int size = 4;
2369 if (info->disassembler_options)
2371 set_default_aarch64_dis_options (info);
2373 parse_aarch64_dis_options (info->disassembler_options);
2375 /* To avoid repeated parsing of these options, we remove them here. */
2376 info->disassembler_options = NULL;
2379 /* Aarch64 instructions are always little-endian */
2380 info->endian_code = BFD_ENDIAN_LITTLE;
2382 /* First check the full symtab for a mapping symbol, even if there
2383 are no usable non-mapping symbols for this address. */
2384 if (info->symtab_size != 0
2385 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
2387 enum map_type type = MAP_INSN;
2392 if (pc <= last_mapping_addr)
2393 last_mapping_sym = -1;
2395 /* Start scanning at the start of the function, or wherever
2396 we finished last time. */
2397 n = info->symtab_pos + 1;
2398 if (n < last_mapping_sym)
2399 n = last_mapping_sym;
2401 /* Scan up to the location being disassembled. */
2402 for (; n < info->symtab_size; n++)
2404 addr = bfd_asymbol_value (info->symtab[n]);
2407 if ((info->section == NULL
2408 || info->section == info->symtab[n]->section)
2409 && get_sym_code_type (info, n, &type))
2418 n = info->symtab_pos;
2419 if (n < last_mapping_sym)
2420 n = last_mapping_sym;
2422 /* No mapping symbol found at this address. Look backwards
2423 for a preceeding one. */
2426 if (get_sym_code_type (info, n, &type))
2435 last_mapping_sym = last_sym;
2438 /* Look a little bit ahead to see if we should print out
2439 less than four bytes of data. If there's a symbol,
2440 mapping or otherwise, after two bytes then don't
2442 if (last_type == MAP_DATA)
2444 size = 4 - (pc & 3);
2445 for (n = last_sym + 1; n < info->symtab_size; n++)
2447 addr = bfd_asymbol_value (info->symtab[n]);
2450 if (addr - pc < size)
2455 /* If the next symbol is after three bytes, we need to
2456 print only part of the data, so that we can use either
2459 size = (pc & 1) ? 1 : 2;
2463 if (last_type == MAP_DATA)
2465 /* size was set above. */
2466 info->bytes_per_chunk = size;
2467 info->display_endian = info->endian;
2468 printer = print_insn_data;
2472 info->bytes_per_chunk = size = INSNLEN;
2473 info->display_endian = info->endian_code;
2474 printer = print_insn_aarch64_word;
2477 status = (*info->read_memory_func) (pc, buffer, size, info);
2480 (*info->memory_error_func) (status, pc, info);
2484 data = bfd_get_bits (buffer, size * 8,
2485 info->display_endian == BFD_ENDIAN_BIG);
2487 (*printer) (pc, data, info);
2493 print_aarch64_disassembler_options (FILE *stream)
2495 fprintf (stream, _("\n\
2496 The following AARCH64 specific disassembler options are supported for use\n\
2497 with the -M switch (multiple options should be separated by commas):\n"));
2499 fprintf (stream, _("\n\
2500 no-aliases Don't print instruction aliases.\n"));
2502 fprintf (stream, _("\n\
2503 aliases Do print instruction aliases.\n"));
2505 #ifdef DEBUG_AARCH64
2506 fprintf (stream, _("\n\
2507 debug_dump Temp switch for debug trace.\n"));
2508 #endif /* DEBUG_AARCH64 */
2510 fprintf (stream, _("\n"));