1 /* aarch64-dis.c -- AArch64 disassembler.
2 Copyright (C) 2009-2018 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"
23 #include "disassemble.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. */
49 \fstatic int no_notes = 1; /* If set do not print disassemble notes in the
50 output as comments. */
53 set_default_aarch64_dis_options (struct disassemble_info *info ATTRIBUTE_UNUSED)
58 parse_aarch64_dis_option (const char *option, unsigned int len ATTRIBUTE_UNUSED)
60 /* Try to match options that are simple flags */
61 if (CONST_STRNEQ (option, "no-aliases"))
67 if (CONST_STRNEQ (option, "aliases"))
73 if (CONST_STRNEQ (option, "no-notes"))
79 if (CONST_STRNEQ (option, "notes"))
86 if (CONST_STRNEQ (option, "debug_dump"))
91 #endif /* DEBUG_AARCH64 */
94 opcodes_error_handler (_("unrecognised disassembler option: %s"), option);
98 parse_aarch64_dis_options (const char *options)
100 const char *option_end;
105 while (*options != '\0')
107 /* Skip empty options. */
114 /* We know that *options is neither NUL or a comma. */
115 option_end = options + 1;
116 while (*option_end != ',' && *option_end != '\0')
119 parse_aarch64_dis_option (options, option_end - options);
121 /* Go on to the next one. If option_end points to a comma, it
122 will be skipped above. */
123 options = option_end;
127 /* Functions doing the instruction disassembling. */
129 /* The unnamed arguments consist of the number of fields and information about
130 these fields where the VALUE will be extracted from CODE and returned.
131 MASK can be zero or the base mask of the opcode.
133 N.B. the fields are required to be in such an order than the most signficant
134 field for VALUE comes the first, e.g. the <index> in
135 SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
136 is encoded in H:L:M in some cases, the fields H:L:M should be passed in
137 the order of H, L, M. */
140 extract_fields (aarch64_insn code, aarch64_insn mask, ...)
143 const aarch64_field *field;
144 enum aarch64_field_kind kind;
148 num = va_arg (va, uint32_t);
150 aarch64_insn value = 0x0;
153 kind = va_arg (va, enum aarch64_field_kind);
154 field = &fields[kind];
155 value <<= field->width;
156 value |= extract_field (kind, code, mask);
161 /* Extract the value of all fields in SELF->fields from instruction CODE.
162 The least significant bit comes from the final field. */
165 extract_all_fields (const aarch64_operand *self, aarch64_insn code)
169 enum aarch64_field_kind kind;
172 for (i = 0; i < ARRAY_SIZE (self->fields) && self->fields[i] != FLD_NIL; ++i)
174 kind = self->fields[i];
175 value <<= fields[kind].width;
176 value |= extract_field (kind, code, 0);
181 /* Sign-extend bit I of VALUE. */
182 static inline int32_t
183 sign_extend (aarch64_insn value, unsigned i)
185 uint32_t ret = value;
188 if ((value >> i) & 0x1)
190 uint32_t val = (uint32_t)(-1) << i;
193 return (int32_t) ret;
196 /* N.B. the following inline helpfer functions create a dependency on the
197 order of operand qualifier enumerators. */
199 /* Given VALUE, return qualifier for a general purpose register. */
200 static inline enum aarch64_opnd_qualifier
201 get_greg_qualifier_from_value (aarch64_insn value)
203 enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_W + value;
205 && aarch64_get_qualifier_standard_value (qualifier) == value);
209 /* Given VALUE, return qualifier for a vector register. This does not support
210 decoding instructions that accept the 2H vector type. */
212 static inline enum aarch64_opnd_qualifier
213 get_vreg_qualifier_from_value (aarch64_insn value)
215 enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_V_8B + value;
217 /* Instructions using vector type 2H should not call this function. Skip over
219 if (qualifier >= AARCH64_OPND_QLF_V_2H)
223 && aarch64_get_qualifier_standard_value (qualifier) == value);
227 /* Given VALUE, return qualifier for an FP or AdvSIMD scalar register. */
228 static inline enum aarch64_opnd_qualifier
229 get_sreg_qualifier_from_value (aarch64_insn value)
231 enum aarch64_opnd_qualifier qualifier = AARCH64_OPND_QLF_S_B + value;
234 && aarch64_get_qualifier_standard_value (qualifier) == value);
238 /* Given the instruction in *INST which is probably half way through the
239 decoding and our caller wants to know the expected qualifier for operand
240 I. Return such a qualifier if we can establish it; otherwise return
241 AARCH64_OPND_QLF_NIL. */
243 static aarch64_opnd_qualifier_t
244 get_expected_qualifier (const aarch64_inst *inst, int i)
246 aarch64_opnd_qualifier_seq_t qualifiers;
247 /* Should not be called if the qualifier is known. */
248 assert (inst->operands[i].qualifier == AARCH64_OPND_QLF_NIL);
249 if (aarch64_find_best_match (inst, inst->opcode->qualifiers_list,
251 return qualifiers[i];
253 return AARCH64_OPND_QLF_NIL;
256 /* Operand extractors. */
259 aarch64_ext_regno (const aarch64_operand *self, aarch64_opnd_info *info,
260 const aarch64_insn code,
261 const aarch64_inst *inst ATTRIBUTE_UNUSED,
262 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
264 info->reg.regno = extract_field (self->fields[0], code, 0);
269 aarch64_ext_regno_pair (const aarch64_operand *self ATTRIBUTE_UNUSED, aarch64_opnd_info *info,
270 const aarch64_insn code ATTRIBUTE_UNUSED,
271 const aarch64_inst *inst ATTRIBUTE_UNUSED,
272 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
274 assert (info->idx == 1
276 info->reg.regno = inst->operands[info->idx - 1].reg.regno + 1;
280 /* e.g. IC <ic_op>{, <Xt>}. */
282 aarch64_ext_regrt_sysins (const aarch64_operand *self, aarch64_opnd_info *info,
283 const aarch64_insn code,
284 const aarch64_inst *inst ATTRIBUTE_UNUSED,
285 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
287 info->reg.regno = extract_field (self->fields[0], code, 0);
288 assert (info->idx == 1
289 && (aarch64_get_operand_class (inst->operands[0].type)
290 == AARCH64_OPND_CLASS_SYSTEM));
291 /* This will make the constraint checking happy and more importantly will
292 help the disassembler determine whether this operand is optional or
294 info->present = aarch64_sys_ins_reg_has_xt (inst->operands[0].sysins_op);
299 /* e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]. */
301 aarch64_ext_reglane (const aarch64_operand *self, aarch64_opnd_info *info,
302 const aarch64_insn code,
303 const aarch64_inst *inst ATTRIBUTE_UNUSED,
304 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
307 info->reglane.regno = extract_field (self->fields[0], code,
310 /* Index and/or type. */
311 if (inst->opcode->iclass == asisdone
312 || inst->opcode->iclass == asimdins)
314 if (info->type == AARCH64_OPND_En
315 && inst->opcode->operands[0] == AARCH64_OPND_Ed)
318 /* index2 for e.g. INS <Vd>.<Ts>[<index1>], <Vn>.<Ts>[<index2>]. */
319 assert (info->idx == 1); /* Vn */
320 aarch64_insn value = extract_field (FLD_imm4, code, 0);
321 /* Depend on AARCH64_OPND_Ed to determine the qualifier. */
322 info->qualifier = get_expected_qualifier (inst, info->idx);
323 shift = get_logsz (aarch64_get_qualifier_esize (info->qualifier));
324 info->reglane.index = value >> shift;
328 /* index and type for e.g. DUP <V><d>, <Vn>.<T>[<index>].
336 aarch64_insn value = extract_field (FLD_imm5, code, 0);
337 while (++pos <= 3 && (value & 0x1) == 0)
341 info->qualifier = get_sreg_qualifier_from_value (pos);
342 info->reglane.index = (unsigned) (value >> 1);
345 else if (inst->opcode->iclass == dotproduct)
347 /* Need information in other operand(s) to help decoding. */
348 info->qualifier = get_expected_qualifier (inst, info->idx);
349 switch (info->qualifier)
351 case AARCH64_OPND_QLF_S_4B:
353 info->reglane.index = extract_fields (code, 0, 2, FLD_H, FLD_L);
354 info->reglane.regno &= 0x1f;
360 else if (inst->opcode->iclass == cryptosm3)
362 /* index for e.g. SM3TT2A <Vd>.4S, <Vn>.4S, <Vm>S[<imm2>]. */
363 info->reglane.index = extract_field (FLD_SM3_imm2, code, 0);
367 /* Index only for e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
368 or SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]. */
370 /* Need information in other operand(s) to help decoding. */
371 info->qualifier = get_expected_qualifier (inst, info->idx);
372 switch (info->qualifier)
374 case AARCH64_OPND_QLF_S_H:
375 if (info->type == AARCH64_OPND_Em16)
378 info->reglane.index = extract_fields (code, 0, 3, FLD_H, FLD_L,
380 info->reglane.regno &= 0xf;
385 info->reglane.index = extract_fields (code, 0, 2, FLD_H, FLD_L);
388 case AARCH64_OPND_QLF_S_S:
390 info->reglane.index = extract_fields (code, 0, 2, FLD_H, FLD_L);
392 case AARCH64_OPND_QLF_S_D:
394 info->reglane.index = extract_field (FLD_H, code, 0);
400 if (inst->opcode->op == OP_FCMLA_ELEM
401 && info->qualifier != AARCH64_OPND_QLF_S_H)
403 /* Complex operand takes two elements. */
404 if (info->reglane.index & 1)
406 info->reglane.index /= 2;
414 aarch64_ext_reglist (const aarch64_operand *self, aarch64_opnd_info *info,
415 const aarch64_insn code,
416 const aarch64_inst *inst ATTRIBUTE_UNUSED,
417 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
420 info->reglist.first_regno = extract_field (self->fields[0], code, 0);
422 info->reglist.num_regs = extract_field (FLD_len, code, 0) + 1;
426 /* Decode Rt and opcode fields of Vt in AdvSIMD load/store instructions. */
428 aarch64_ext_ldst_reglist (const aarch64_operand *self ATTRIBUTE_UNUSED,
429 aarch64_opnd_info *info, const aarch64_insn code,
430 const aarch64_inst *inst,
431 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
434 /* Number of elements in each structure to be loaded/stored. */
435 unsigned expected_num = get_opcode_dependent_value (inst->opcode);
439 unsigned is_reserved;
441 unsigned num_elements;
457 info->reglist.first_regno = extract_field (FLD_Rt, code, 0);
459 value = extract_field (FLD_opcode, code, 0);
460 /* PR 21595: Check for a bogus value. */
461 if (value >= ARRAY_SIZE (data))
463 if (expected_num != data[value].num_elements || data[value].is_reserved)
465 info->reglist.num_regs = data[value].num_regs;
470 /* Decode Rt and S fields of Vt in AdvSIMD load single structure to all
471 lanes instructions. */
473 aarch64_ext_ldst_reglist_r (const aarch64_operand *self ATTRIBUTE_UNUSED,
474 aarch64_opnd_info *info, const aarch64_insn code,
475 const aarch64_inst *inst,
476 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
481 info->reglist.first_regno = extract_field (FLD_Rt, code, 0);
483 value = extract_field (FLD_S, code, 0);
485 /* Number of registers is equal to the number of elements in
486 each structure to be loaded/stored. */
487 info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
488 assert (info->reglist.num_regs >= 1 && info->reglist.num_regs <= 4);
490 /* Except when it is LD1R. */
491 if (info->reglist.num_regs == 1 && value == (aarch64_insn) 1)
492 info->reglist.num_regs = 2;
497 /* Decode Q, opcode<2:1>, S, size and Rt fields of Vt in AdvSIMD
498 load/store single element instructions. */
500 aarch64_ext_ldst_elemlist (const aarch64_operand *self ATTRIBUTE_UNUSED,
501 aarch64_opnd_info *info, const aarch64_insn code,
502 const aarch64_inst *inst ATTRIBUTE_UNUSED,
503 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
505 aarch64_field field = {0, 0};
506 aarch64_insn QSsize; /* fields Q:S:size. */
507 aarch64_insn opcodeh2; /* opcode<2:1> */
510 info->reglist.first_regno = extract_field (FLD_Rt, code, 0);
512 /* Decode the index, opcode<2:1> and size. */
513 gen_sub_field (FLD_asisdlso_opcode, 1, 2, &field);
514 opcodeh2 = extract_field_2 (&field, code, 0);
515 QSsize = extract_fields (code, 0, 3, FLD_Q, FLD_S, FLD_vldst_size);
519 info->qualifier = AARCH64_OPND_QLF_S_B;
520 /* Index encoded in "Q:S:size". */
521 info->reglist.index = QSsize;
527 info->qualifier = AARCH64_OPND_QLF_S_H;
528 /* Index encoded in "Q:S:size<1>". */
529 info->reglist.index = QSsize >> 1;
532 if ((QSsize >> 1) & 0x1)
535 if ((QSsize & 0x1) == 0)
537 info->qualifier = AARCH64_OPND_QLF_S_S;
538 /* Index encoded in "Q:S". */
539 info->reglist.index = QSsize >> 2;
543 if (extract_field (FLD_S, code, 0))
546 info->qualifier = AARCH64_OPND_QLF_S_D;
547 /* Index encoded in "Q". */
548 info->reglist.index = QSsize >> 3;
555 info->reglist.has_index = 1;
556 info->reglist.num_regs = 0;
557 /* Number of registers is equal to the number of elements in
558 each structure to be loaded/stored. */
559 info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
560 assert (info->reglist.num_regs >= 1 && info->reglist.num_regs <= 4);
565 /* Decode fields immh:immb and/or Q for e.g.
566 SSHR <Vd>.<T>, <Vn>.<T>, #<shift>
567 or SSHR <V><d>, <V><n>, #<shift>. */
570 aarch64_ext_advsimd_imm_shift (const aarch64_operand *self ATTRIBUTE_UNUSED,
571 aarch64_opnd_info *info, const aarch64_insn code,
572 const aarch64_inst *inst,
573 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
576 aarch64_insn Q, imm, immh;
577 enum aarch64_insn_class iclass = inst->opcode->iclass;
579 immh = extract_field (FLD_immh, code, 0);
582 imm = extract_fields (code, 0, 2, FLD_immh, FLD_immb);
584 /* Get highest set bit in immh. */
585 while (--pos >= 0 && (immh & 0x8) == 0)
588 assert ((iclass == asimdshf || iclass == asisdshf)
589 && (info->type == AARCH64_OPND_IMM_VLSR
590 || info->type == AARCH64_OPND_IMM_VLSL));
592 if (iclass == asimdshf)
594 Q = extract_field (FLD_Q, code, 0);
596 0000 x SEE AdvSIMD modified immediate
606 get_vreg_qualifier_from_value ((pos << 1) | (int) Q);
609 info->qualifier = get_sreg_qualifier_from_value (pos);
611 if (info->type == AARCH64_OPND_IMM_VLSR)
613 0000 SEE AdvSIMD modified immediate
614 0001 (16-UInt(immh:immb))
615 001x (32-UInt(immh:immb))
616 01xx (64-UInt(immh:immb))
617 1xxx (128-UInt(immh:immb)) */
618 info->imm.value = (16 << pos) - imm;
622 0000 SEE AdvSIMD modified immediate
623 0001 (UInt(immh:immb)-8)
624 001x (UInt(immh:immb)-16)
625 01xx (UInt(immh:immb)-32)
626 1xxx (UInt(immh:immb)-64) */
627 info->imm.value = imm - (8 << pos);
632 /* Decode shift immediate for e.g. sshr (imm). */
634 aarch64_ext_shll_imm (const aarch64_operand *self ATTRIBUTE_UNUSED,
635 aarch64_opnd_info *info, const aarch64_insn code,
636 const aarch64_inst *inst ATTRIBUTE_UNUSED,
637 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
641 val = extract_field (FLD_size, code, 0);
644 case 0: imm = 8; break;
645 case 1: imm = 16; break;
646 case 2: imm = 32; break;
647 default: return FALSE;
649 info->imm.value = imm;
653 /* Decode imm for e.g. BFM <Wd>, <Wn>, #<immr>, #<imms>.
654 value in the field(s) will be extracted as unsigned immediate value. */
656 aarch64_ext_imm (const aarch64_operand *self, aarch64_opnd_info *info,
657 const aarch64_insn code,
658 const aarch64_inst *inst ATTRIBUTE_UNUSED,
659 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
663 imm = extract_all_fields (self, code);
665 if (operand_need_sign_extension (self))
666 imm = sign_extend (imm, get_operand_fields_width (self) - 1);
668 if (operand_need_shift_by_two (self))
671 if (info->type == AARCH64_OPND_ADDR_ADRP)
674 info->imm.value = imm;
678 /* Decode imm and its shifter for e.g. MOVZ <Wd>, #<imm16>{, LSL #<shift>}. */
680 aarch64_ext_imm_half (const aarch64_operand *self, aarch64_opnd_info *info,
681 const aarch64_insn code,
682 const aarch64_inst *inst ATTRIBUTE_UNUSED,
683 aarch64_operand_error *errors)
685 aarch64_ext_imm (self, info, code, inst, errors);
686 info->shifter.kind = AARCH64_MOD_LSL;
687 info->shifter.amount = extract_field (FLD_hw, code, 0) << 4;
691 /* Decode cmode and "a:b:c:d:e:f:g:h" for e.g.
692 MOVI <Vd>.<T>, #<imm8> {, LSL #<amount>}. */
694 aarch64_ext_advsimd_imm_modified (const aarch64_operand *self ATTRIBUTE_UNUSED,
695 aarch64_opnd_info *info,
696 const aarch64_insn code,
697 const aarch64_inst *inst ATTRIBUTE_UNUSED,
698 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
701 enum aarch64_opnd_qualifier opnd0_qualifier = inst->operands[0].qualifier;
702 aarch64_field field = {0, 0};
704 assert (info->idx == 1);
706 if (info->type == AARCH64_OPND_SIMD_FPIMM)
709 /* a:b:c:d:e:f:g:h */
710 imm = extract_fields (code, 0, 2, FLD_abc, FLD_defgh);
711 if (!info->imm.is_fp && aarch64_get_qualifier_esize (opnd0_qualifier) == 8)
713 /* Either MOVI <Dd>, #<imm>
714 or MOVI <Vd>.2D, #<imm>.
715 <imm> is a 64-bit immediate
716 'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh',
717 encoded in "a:b:c:d:e:f:g:h". */
719 unsigned abcdefgh = imm;
720 for (imm = 0ull, i = 0; i < 8; i++)
721 if (((abcdefgh >> i) & 0x1) != 0)
722 imm |= 0xffull << (8 * i);
724 info->imm.value = imm;
727 info->qualifier = get_expected_qualifier (inst, info->idx);
728 switch (info->qualifier)
730 case AARCH64_OPND_QLF_NIL:
732 info->shifter.kind = AARCH64_MOD_NONE;
734 case AARCH64_OPND_QLF_LSL:
736 info->shifter.kind = AARCH64_MOD_LSL;
737 switch (aarch64_get_qualifier_esize (opnd0_qualifier))
739 case 4: gen_sub_field (FLD_cmode, 1, 2, &field); break; /* per word */
740 case 2: gen_sub_field (FLD_cmode, 1, 1, &field); break; /* per half */
741 case 1: gen_sub_field (FLD_cmode, 1, 0, &field); break; /* per byte */
742 default: assert (0); return FALSE;
744 /* 00: 0; 01: 8; 10:16; 11:24. */
745 info->shifter.amount = extract_field_2 (&field, code, 0) << 3;
747 case AARCH64_OPND_QLF_MSL:
749 info->shifter.kind = AARCH64_MOD_MSL;
750 gen_sub_field (FLD_cmode, 0, 1, &field); /* per word */
751 info->shifter.amount = extract_field_2 (&field, code, 0) ? 16 : 8;
761 /* Decode an 8-bit floating-point immediate. */
763 aarch64_ext_fpimm (const aarch64_operand *self, aarch64_opnd_info *info,
764 const aarch64_insn code,
765 const aarch64_inst *inst ATTRIBUTE_UNUSED,
766 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
768 info->imm.value = extract_all_fields (self, code);
773 /* Decode a 1-bit rotate immediate (#90 or #270). */
775 aarch64_ext_imm_rotate1 (const aarch64_operand *self, aarch64_opnd_info *info,
776 const aarch64_insn code,
777 const aarch64_inst *inst ATTRIBUTE_UNUSED,
778 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
780 uint64_t rot = extract_field (self->fields[0], code, 0);
782 info->imm.value = rot * 180 + 90;
786 /* Decode a 2-bit rotate immediate (#0, #90, #180 or #270). */
788 aarch64_ext_imm_rotate2 (const aarch64_operand *self, aarch64_opnd_info *info,
789 const aarch64_insn code,
790 const aarch64_inst *inst ATTRIBUTE_UNUSED,
791 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
793 uint64_t rot = extract_field (self->fields[0], code, 0);
795 info->imm.value = rot * 90;
799 /* Decode scale for e.g. SCVTF <Dd>, <Wn>, #<fbits>. */
801 aarch64_ext_fbits (const aarch64_operand *self ATTRIBUTE_UNUSED,
802 aarch64_opnd_info *info, const aarch64_insn code,
803 const aarch64_inst *inst ATTRIBUTE_UNUSED,
804 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
806 info->imm.value = 64- extract_field (FLD_scale, code, 0);
810 /* Decode arithmetic immediate for e.g.
811 SUBS <Wd>, <Wn|WSP>, #<imm> {, <shift>}. */
813 aarch64_ext_aimm (const aarch64_operand *self ATTRIBUTE_UNUSED,
814 aarch64_opnd_info *info, const aarch64_insn code,
815 const aarch64_inst *inst ATTRIBUTE_UNUSED,
816 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
820 info->shifter.kind = AARCH64_MOD_LSL;
822 value = extract_field (FLD_shift, code, 0);
825 info->shifter.amount = value ? 12 : 0;
826 /* imm12 (unsigned) */
827 info->imm.value = extract_field (FLD_imm12, code, 0);
832 /* Return true if VALUE is a valid logical immediate encoding, storing the
833 decoded value in *RESULT if so. ESIZE is the number of bytes in the
834 decoded immediate. */
836 decode_limm (uint32_t esize, aarch64_insn value, int64_t *result)
842 /* value is N:immr:imms. */
844 R = (value >> 6) & 0x3f;
845 N = (value >> 12) & 0x1;
847 /* The immediate value is S+1 bits to 1, left rotated by SIMDsize - R
848 (in other words, right rotated by R), then replicated. */
852 mask = 0xffffffffffffffffull;
858 case 0x00 ... 0x1f: /* 0xxxxx */ simd_size = 32; break;
859 case 0x20 ... 0x2f: /* 10xxxx */ simd_size = 16; S &= 0xf; break;
860 case 0x30 ... 0x37: /* 110xxx */ simd_size = 8; S &= 0x7; break;
861 case 0x38 ... 0x3b: /* 1110xx */ simd_size = 4; S &= 0x3; break;
862 case 0x3c ... 0x3d: /* 11110x */ simd_size = 2; S &= 0x1; break;
863 default: return FALSE;
865 mask = (1ull << simd_size) - 1;
866 /* Top bits are IGNORED. */
870 if (simd_size > esize * 8)
873 /* NOTE: if S = simd_size - 1 we get 0xf..f which is rejected. */
874 if (S == simd_size - 1)
876 /* S+1 consecutive bits to 1. */
877 /* NOTE: S can't be 63 due to detection above. */
878 imm = (1ull << (S + 1)) - 1;
879 /* Rotate to the left by simd_size - R. */
881 imm = ((imm << (simd_size - R)) & mask) | (imm >> R);
882 /* Replicate the value according to SIMD size. */
885 case 2: imm = (imm << 2) | imm;
887 case 4: imm = (imm << 4) | imm;
889 case 8: imm = (imm << 8) | imm;
891 case 16: imm = (imm << 16) | imm;
893 case 32: imm = (imm << 32) | imm;
896 default: assert (0); return 0;
899 *result = imm & ~((uint64_t) -1 << (esize * 4) << (esize * 4));
904 /* Decode a logical immediate for e.g. ORR <Wd|WSP>, <Wn>, #<imm>. */
906 aarch64_ext_limm (const aarch64_operand *self,
907 aarch64_opnd_info *info, const aarch64_insn code,
908 const aarch64_inst *inst,
909 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
914 value = extract_fields (code, 0, 3, self->fields[0], self->fields[1],
916 esize = aarch64_get_qualifier_esize (inst->operands[0].qualifier);
917 return decode_limm (esize, value, &info->imm.value);
920 /* Decode a logical immediate for the BIC alias of AND (etc.). */
922 aarch64_ext_inv_limm (const aarch64_operand *self,
923 aarch64_opnd_info *info, const aarch64_insn code,
924 const aarch64_inst *inst,
925 aarch64_operand_error *errors)
927 if (!aarch64_ext_limm (self, info, code, inst, errors))
929 info->imm.value = ~info->imm.value;
933 /* Decode Ft for e.g. STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]
934 or LDP <Qt1>, <Qt2>, [<Xn|SP>], #<imm>. */
936 aarch64_ext_ft (const aarch64_operand *self ATTRIBUTE_UNUSED,
937 aarch64_opnd_info *info,
938 const aarch64_insn code, const aarch64_inst *inst,
939 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
944 info->reg.regno = extract_field (FLD_Rt, code, 0);
947 value = extract_field (FLD_ldst_size, code, 0);
948 if (inst->opcode->iclass == ldstpair_indexed
949 || inst->opcode->iclass == ldstnapair_offs
950 || inst->opcode->iclass == ldstpair_off
951 || inst->opcode->iclass == loadlit)
953 enum aarch64_opnd_qualifier qualifier;
956 case 0: qualifier = AARCH64_OPND_QLF_S_S; break;
957 case 1: qualifier = AARCH64_OPND_QLF_S_D; break;
958 case 2: qualifier = AARCH64_OPND_QLF_S_Q; break;
959 default: return FALSE;
961 info->qualifier = qualifier;
966 value = extract_fields (code, 0, 2, FLD_opc1, FLD_ldst_size);
969 info->qualifier = get_sreg_qualifier_from_value (value);
975 /* Decode the address operand for e.g. STXRB <Ws>, <Wt>, [<Xn|SP>{,#0}]. */
977 aarch64_ext_addr_simple (const aarch64_operand *self ATTRIBUTE_UNUSED,
978 aarch64_opnd_info *info,
980 const aarch64_inst *inst ATTRIBUTE_UNUSED,
981 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
984 info->addr.base_regno = extract_field (FLD_Rn, code, 0);
988 /* Decode the address operand for e.g.
989 stlur <Xt>, [<Xn|SP>{, <amount>}]. */
991 aarch64_ext_addr_offset (const aarch64_operand *self ATTRIBUTE_UNUSED,
992 aarch64_opnd_info *info,
993 aarch64_insn code, const aarch64_inst *inst,
994 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
996 info->qualifier = get_expected_qualifier (inst, info->idx);
999 info->addr.base_regno = extract_field (self->fields[0], code, 0);
1002 aarch64_insn imm = extract_fields (code, 0, 1, self->fields[1]);
1003 info->addr.offset.imm = sign_extend (imm, 8);
1004 if (extract_field (self->fields[2], code, 0) == 1) {
1005 info->addr.writeback = 1;
1006 info->addr.preind = 1;
1011 /* Decode the address operand for e.g.
1012 STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]. */
1014 aarch64_ext_addr_regoff (const aarch64_operand *self ATTRIBUTE_UNUSED,
1015 aarch64_opnd_info *info,
1016 aarch64_insn code, const aarch64_inst *inst,
1017 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1019 aarch64_insn S, value;
1022 info->addr.base_regno = extract_field (FLD_Rn, code, 0);
1024 info->addr.offset.regno = extract_field (FLD_Rm, code, 0);
1026 value = extract_field (FLD_option, code, 0);
1027 info->shifter.kind =
1028 aarch64_get_operand_modifier_from_value (value, TRUE /* extend_p */);
1029 /* Fix-up the shifter kind; although the table-driven approach is
1030 efficient, it is slightly inflexible, thus needing this fix-up. */
1031 if (info->shifter.kind == AARCH64_MOD_UXTX)
1032 info->shifter.kind = AARCH64_MOD_LSL;
1034 S = extract_field (FLD_S, code, 0);
1037 info->shifter.amount = 0;
1038 info->shifter.amount_present = 0;
1043 /* Need information in other operand(s) to help achieve the decoding
1045 info->qualifier = get_expected_qualifier (inst, info->idx);
1046 /* Get the size of the data element that is accessed, which may be
1047 different from that of the source register size, e.g. in strb/ldrb. */
1048 size = aarch64_get_qualifier_esize (info->qualifier);
1049 info->shifter.amount = get_logsz (size);
1050 info->shifter.amount_present = 1;
1056 /* Decode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>], #<simm>. */
1058 aarch64_ext_addr_simm (const aarch64_operand *self, aarch64_opnd_info *info,
1059 aarch64_insn code, const aarch64_inst *inst,
1060 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1063 info->qualifier = get_expected_qualifier (inst, info->idx);
1066 info->addr.base_regno = extract_field (FLD_Rn, code, 0);
1067 /* simm (imm9 or imm7) */
1068 imm = extract_field (self->fields[0], code, 0);
1069 info->addr.offset.imm = sign_extend (imm, fields[self->fields[0]].width - 1);
1070 if (self->fields[0] == FLD_imm7)
1071 /* scaled immediate in ld/st pair instructions. */
1072 info->addr.offset.imm *= aarch64_get_qualifier_esize (info->qualifier);
1074 if (inst->opcode->iclass == ldst_unscaled
1075 || inst->opcode->iclass == ldstnapair_offs
1076 || inst->opcode->iclass == ldstpair_off
1077 || inst->opcode->iclass == ldst_unpriv)
1078 info->addr.writeback = 0;
1081 /* pre/post- index */
1082 info->addr.writeback = 1;
1083 if (extract_field (self->fields[1], code, 0) == 1)
1084 info->addr.preind = 1;
1086 info->addr.postind = 1;
1092 /* Decode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>{, #<simm>}]. */
1094 aarch64_ext_addr_uimm12 (const aarch64_operand *self, aarch64_opnd_info *info,
1096 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1097 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1100 info->qualifier = get_expected_qualifier (inst, info->idx);
1101 shift = get_logsz (aarch64_get_qualifier_esize (info->qualifier));
1103 info->addr.base_regno = extract_field (self->fields[0], code, 0);
1105 info->addr.offset.imm = extract_field (self->fields[1], code, 0) << shift;
1109 /* Decode the address operand for e.g. LDRAA <Xt>, [<Xn|SP>{, #<simm>}]. */
1111 aarch64_ext_addr_simm10 (const aarch64_operand *self, aarch64_opnd_info *info,
1113 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1114 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1118 info->qualifier = get_expected_qualifier (inst, info->idx);
1120 info->addr.base_regno = extract_field (self->fields[0], code, 0);
1122 imm = extract_fields (code, 0, 2, self->fields[1], self->fields[2]);
1123 info->addr.offset.imm = sign_extend (imm, 9) << 3;
1124 if (extract_field (self->fields[3], code, 0) == 1) {
1125 info->addr.writeback = 1;
1126 info->addr.preind = 1;
1131 /* Decode the address operand for e.g.
1132 LD1 {<Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>}, [<Xn|SP>], <Xm|#<amount>>. */
1134 aarch64_ext_simd_addr_post (const aarch64_operand *self ATTRIBUTE_UNUSED,
1135 aarch64_opnd_info *info,
1136 aarch64_insn code, const aarch64_inst *inst,
1137 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1139 /* The opcode dependent area stores the number of elements in
1140 each structure to be loaded/stored. */
1141 int is_ld1r = get_opcode_dependent_value (inst->opcode) == 1;
1144 info->addr.base_regno = extract_field (FLD_Rn, code, 0);
1145 /* Rm | #<amount> */
1146 info->addr.offset.regno = extract_field (FLD_Rm, code, 0);
1147 if (info->addr.offset.regno == 31)
1149 if (inst->opcode->operands[0] == AARCH64_OPND_LVt_AL)
1150 /* Special handling of loading single structure to all lane. */
1151 info->addr.offset.imm = (is_ld1r ? 1
1152 : inst->operands[0].reglist.num_regs)
1153 * aarch64_get_qualifier_esize (inst->operands[0].qualifier);
1155 info->addr.offset.imm = inst->operands[0].reglist.num_regs
1156 * aarch64_get_qualifier_esize (inst->operands[0].qualifier)
1157 * aarch64_get_qualifier_nelem (inst->operands[0].qualifier);
1160 info->addr.offset.is_reg = 1;
1161 info->addr.writeback = 1;
1166 /* Decode the condition operand for e.g. CSEL <Xd>, <Xn>, <Xm>, <cond>. */
1168 aarch64_ext_cond (const aarch64_operand *self ATTRIBUTE_UNUSED,
1169 aarch64_opnd_info *info,
1170 aarch64_insn code, const aarch64_inst *inst ATTRIBUTE_UNUSED,
1171 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1175 value = extract_field (FLD_cond, code, 0);
1176 info->cond = get_cond_from_value (value);
1180 /* Decode the system register operand for e.g. MRS <Xt>, <systemreg>. */
1182 aarch64_ext_sysreg (const aarch64_operand *self ATTRIBUTE_UNUSED,
1183 aarch64_opnd_info *info,
1185 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1186 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1188 /* op0:op1:CRn:CRm:op2 */
1189 info->sysreg.value = extract_fields (code, 0, 5, FLD_op0, FLD_op1, FLD_CRn,
1191 info->sysreg.flags = 0;
1193 /* If a system instruction, check which restrictions should be on the register
1194 value during decoding, these will be enforced then. */
1195 if (inst->opcode->iclass == ic_system)
1197 /* Check to see if it's read-only, else check if it's write only.
1198 if it's both or unspecified don't care. */
1199 if ((inst->opcode->flags & (F_SYS_READ | F_SYS_WRITE)) == F_SYS_READ)
1200 info->sysreg.flags = F_REG_READ;
1201 else if ((inst->opcode->flags & (F_SYS_READ | F_SYS_WRITE))
1203 info->sysreg.flags = F_REG_WRITE;
1209 /* Decode the PSTATE field operand for e.g. MSR <pstatefield>, #<imm>. */
1211 aarch64_ext_pstatefield (const aarch64_operand *self ATTRIBUTE_UNUSED,
1212 aarch64_opnd_info *info, aarch64_insn code,
1213 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1214 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1218 info->pstatefield = extract_fields (code, 0, 2, FLD_op1, FLD_op2);
1219 for (i = 0; aarch64_pstatefields[i].name != NULL; ++i)
1220 if (aarch64_pstatefields[i].value == (aarch64_insn)info->pstatefield)
1222 /* Reserved value in <pstatefield>. */
1226 /* Decode the system instruction op operand for e.g. AT <at_op>, <Xt>. */
1228 aarch64_ext_sysins_op (const aarch64_operand *self ATTRIBUTE_UNUSED,
1229 aarch64_opnd_info *info,
1231 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1232 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1236 const aarch64_sys_ins_reg *sysins_ops;
1237 /* op0:op1:CRn:CRm:op2 */
1238 value = extract_fields (code, 0, 5,
1239 FLD_op0, FLD_op1, FLD_CRn,
1244 case AARCH64_OPND_SYSREG_AT: sysins_ops = aarch64_sys_regs_at; break;
1245 case AARCH64_OPND_SYSREG_DC: sysins_ops = aarch64_sys_regs_dc; break;
1246 case AARCH64_OPND_SYSREG_IC: sysins_ops = aarch64_sys_regs_ic; break;
1247 case AARCH64_OPND_SYSREG_TLBI: sysins_ops = aarch64_sys_regs_tlbi; break;
1248 default: assert (0); return FALSE;
1251 for (i = 0; sysins_ops[i].name != NULL; ++i)
1252 if (sysins_ops[i].value == value)
1254 info->sysins_op = sysins_ops + i;
1255 DEBUG_TRACE ("%s found value: %x, has_xt: %d, i: %d.",
1256 info->sysins_op->name,
1257 (unsigned)info->sysins_op->value,
1258 aarch64_sys_ins_reg_has_xt (info->sysins_op), i);
1265 /* Decode the memory barrier option operand for e.g. DMB <option>|#<imm>. */
1268 aarch64_ext_barrier (const aarch64_operand *self ATTRIBUTE_UNUSED,
1269 aarch64_opnd_info *info,
1271 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1272 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1275 info->barrier = aarch64_barrier_options + extract_field (FLD_CRm, code, 0);
1279 /* Decode the prefetch operation option operand for e.g.
1280 PRFM <prfop>, [<Xn|SP>{, #<pimm>}]. */
1283 aarch64_ext_prfop (const aarch64_operand *self ATTRIBUTE_UNUSED,
1284 aarch64_opnd_info *info,
1285 aarch64_insn code, const aarch64_inst *inst ATTRIBUTE_UNUSED,
1286 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1289 info->prfop = aarch64_prfops + extract_field (FLD_Rt, code, 0);
1293 /* Decode the hint number for an alias taking an operand. Set info->hint_option
1294 to the matching name/value pair in aarch64_hint_options. */
1297 aarch64_ext_hint (const aarch64_operand *self ATTRIBUTE_UNUSED,
1298 aarch64_opnd_info *info,
1300 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1301 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1304 unsigned hint_number;
1307 hint_number = extract_fields (code, 0, 2, FLD_CRm, FLD_op2);
1309 for (i = 0; aarch64_hint_options[i].name != NULL; i++)
1311 if (hint_number == aarch64_hint_options[i].value)
1313 info->hint_option = &(aarch64_hint_options[i]);
1321 /* Decode the extended register operand for e.g.
1322 STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]. */
1324 aarch64_ext_reg_extended (const aarch64_operand *self ATTRIBUTE_UNUSED,
1325 aarch64_opnd_info *info,
1327 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1328 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1333 info->reg.regno = extract_field (FLD_Rm, code, 0);
1335 value = extract_field (FLD_option, code, 0);
1336 info->shifter.kind =
1337 aarch64_get_operand_modifier_from_value (value, TRUE /* extend_p */);
1339 info->shifter.amount = extract_field (FLD_imm3, code, 0);
1341 /* This makes the constraint checking happy. */
1342 info->shifter.operator_present = 1;
1344 /* Assume inst->operands[0].qualifier has been resolved. */
1345 assert (inst->operands[0].qualifier != AARCH64_OPND_QLF_NIL);
1346 info->qualifier = AARCH64_OPND_QLF_W;
1347 if (inst->operands[0].qualifier == AARCH64_OPND_QLF_X
1348 && (info->shifter.kind == AARCH64_MOD_UXTX
1349 || info->shifter.kind == AARCH64_MOD_SXTX))
1350 info->qualifier = AARCH64_OPND_QLF_X;
1355 /* Decode the shifted register operand for e.g.
1356 SUBS <Xd>, <Xn>, <Xm> {, <shift> #<amount>}. */
1358 aarch64_ext_reg_shifted (const aarch64_operand *self ATTRIBUTE_UNUSED,
1359 aarch64_opnd_info *info,
1361 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1362 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1367 info->reg.regno = extract_field (FLD_Rm, code, 0);
1369 value = extract_field (FLD_shift, code, 0);
1370 info->shifter.kind =
1371 aarch64_get_operand_modifier_from_value (value, FALSE /* extend_p */);
1372 if (info->shifter.kind == AARCH64_MOD_ROR
1373 && inst->opcode->iclass != log_shift)
1374 /* ROR is not available for the shifted register operand in arithmetic
1378 info->shifter.amount = extract_field (FLD_imm6, code, 0);
1380 /* This makes the constraint checking happy. */
1381 info->shifter.operator_present = 1;
1386 /* Decode an SVE address [<base>, #<offset>*<factor>, MUL VL],
1387 where <offset> is given by the OFFSET parameter and where <factor> is
1388 1 plus SELF's operand-dependent value. fields[0] specifies the field
1389 that holds <base>. */
1391 aarch64_ext_sve_addr_reg_mul_vl (const aarch64_operand *self,
1392 aarch64_opnd_info *info, aarch64_insn code,
1395 info->addr.base_regno = extract_field (self->fields[0], code, 0);
1396 info->addr.offset.imm = offset * (1 + get_operand_specific_data (self));
1397 info->addr.offset.is_reg = FALSE;
1398 info->addr.writeback = FALSE;
1399 info->addr.preind = TRUE;
1401 info->shifter.kind = AARCH64_MOD_MUL_VL;
1402 info->shifter.amount = 1;
1403 info->shifter.operator_present = (info->addr.offset.imm != 0);
1404 info->shifter.amount_present = FALSE;
1408 /* Decode an SVE address [<base>, #<simm4>*<factor>, MUL VL],
1409 where <simm4> is a 4-bit signed value and where <factor> is 1 plus
1410 SELF's operand-dependent value. fields[0] specifies the field that
1411 holds <base>. <simm4> is encoded in the SVE_imm4 field. */
1413 aarch64_ext_sve_addr_ri_s4xvl (const aarch64_operand *self,
1414 aarch64_opnd_info *info, aarch64_insn code,
1415 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1416 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1420 offset = extract_field (FLD_SVE_imm4, code, 0);
1421 offset = ((offset + 8) & 15) - 8;
1422 return aarch64_ext_sve_addr_reg_mul_vl (self, info, code, offset);
1425 /* Decode an SVE address [<base>, #<simm6>*<factor>, MUL VL],
1426 where <simm6> is a 6-bit signed value and where <factor> is 1 plus
1427 SELF's operand-dependent value. fields[0] specifies the field that
1428 holds <base>. <simm6> is encoded in the SVE_imm6 field. */
1430 aarch64_ext_sve_addr_ri_s6xvl (const aarch64_operand *self,
1431 aarch64_opnd_info *info, aarch64_insn code,
1432 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1433 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1437 offset = extract_field (FLD_SVE_imm6, code, 0);
1438 offset = (((offset + 32) & 63) - 32);
1439 return aarch64_ext_sve_addr_reg_mul_vl (self, info, code, offset);
1442 /* Decode an SVE address [<base>, #<simm9>*<factor>, MUL VL],
1443 where <simm9> is a 9-bit signed value and where <factor> is 1 plus
1444 SELF's operand-dependent value. fields[0] specifies the field that
1445 holds <base>. <simm9> is encoded in the concatenation of the SVE_imm6
1446 and imm3 fields, with imm3 being the less-significant part. */
1448 aarch64_ext_sve_addr_ri_s9xvl (const aarch64_operand *self,
1449 aarch64_opnd_info *info,
1451 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1452 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1456 offset = extract_fields (code, 0, 2, FLD_SVE_imm6, FLD_imm3);
1457 offset = (((offset + 256) & 511) - 256);
1458 return aarch64_ext_sve_addr_reg_mul_vl (self, info, code, offset);
1461 /* Decode an SVE address [<base>, #<offset> << <shift>], where <offset>
1462 is given by the OFFSET parameter and where <shift> is SELF's operand-
1463 dependent value. fields[0] specifies the base register field <base>. */
1465 aarch64_ext_sve_addr_reg_imm (const aarch64_operand *self,
1466 aarch64_opnd_info *info, aarch64_insn code,
1469 info->addr.base_regno = extract_field (self->fields[0], code, 0);
1470 info->addr.offset.imm = offset * (1 << get_operand_specific_data (self));
1471 info->addr.offset.is_reg = FALSE;
1472 info->addr.writeback = FALSE;
1473 info->addr.preind = TRUE;
1474 info->shifter.operator_present = FALSE;
1475 info->shifter.amount_present = FALSE;
1479 /* Decode an SVE address [X<n>, #<SVE_imm4> << <shift>], where <SVE_imm4>
1480 is a 4-bit signed number and where <shift> is SELF's operand-dependent
1481 value. fields[0] specifies the base register field. */
1483 aarch64_ext_sve_addr_ri_s4 (const aarch64_operand *self,
1484 aarch64_opnd_info *info, aarch64_insn code,
1485 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1486 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1488 int offset = sign_extend (extract_field (FLD_SVE_imm4, code, 0), 3);
1489 return aarch64_ext_sve_addr_reg_imm (self, info, code, offset);
1492 /* Decode an SVE address [X<n>, #<SVE_imm6> << <shift>], where <SVE_imm6>
1493 is a 6-bit unsigned number and where <shift> is SELF's operand-dependent
1494 value. fields[0] specifies the base register field. */
1496 aarch64_ext_sve_addr_ri_u6 (const aarch64_operand *self,
1497 aarch64_opnd_info *info, aarch64_insn code,
1498 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1499 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1501 int offset = extract_field (FLD_SVE_imm6, code, 0);
1502 return aarch64_ext_sve_addr_reg_imm (self, info, code, offset);
1505 /* Decode an SVE address [X<n>, X<m>{, LSL #<shift>}], where <shift>
1506 is SELF's operand-dependent value. fields[0] specifies the base
1507 register field and fields[1] specifies the offset register field. */
1509 aarch64_ext_sve_addr_rr_lsl (const aarch64_operand *self,
1510 aarch64_opnd_info *info, aarch64_insn code,
1511 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1512 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1516 index_regno = extract_field (self->fields[1], code, 0);
1517 if (index_regno == 31 && (self->flags & OPD_F_NO_ZR) != 0)
1520 info->addr.base_regno = extract_field (self->fields[0], code, 0);
1521 info->addr.offset.regno = index_regno;
1522 info->addr.offset.is_reg = TRUE;
1523 info->addr.writeback = FALSE;
1524 info->addr.preind = TRUE;
1525 info->shifter.kind = AARCH64_MOD_LSL;
1526 info->shifter.amount = get_operand_specific_data (self);
1527 info->shifter.operator_present = (info->shifter.amount != 0);
1528 info->shifter.amount_present = (info->shifter.amount != 0);
1532 /* Decode an SVE address [X<n>, Z<m>.<T>, (S|U)XTW {#<shift>}], where
1533 <shift> is SELF's operand-dependent value. fields[0] specifies the
1534 base register field, fields[1] specifies the offset register field and
1535 fields[2] is a single-bit field that selects SXTW over UXTW. */
1537 aarch64_ext_sve_addr_rz_xtw (const aarch64_operand *self,
1538 aarch64_opnd_info *info, aarch64_insn code,
1539 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1540 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1542 info->addr.base_regno = extract_field (self->fields[0], code, 0);
1543 info->addr.offset.regno = extract_field (self->fields[1], code, 0);
1544 info->addr.offset.is_reg = TRUE;
1545 info->addr.writeback = FALSE;
1546 info->addr.preind = TRUE;
1547 if (extract_field (self->fields[2], code, 0))
1548 info->shifter.kind = AARCH64_MOD_SXTW;
1550 info->shifter.kind = AARCH64_MOD_UXTW;
1551 info->shifter.amount = get_operand_specific_data (self);
1552 info->shifter.operator_present = TRUE;
1553 info->shifter.amount_present = (info->shifter.amount != 0);
1557 /* Decode an SVE address [Z<n>.<T>, #<imm5> << <shift>], where <imm5> is a
1558 5-bit unsigned number and where <shift> is SELF's operand-dependent value.
1559 fields[0] specifies the base register field. */
1561 aarch64_ext_sve_addr_zi_u5 (const aarch64_operand *self,
1562 aarch64_opnd_info *info, aarch64_insn code,
1563 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1564 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1566 int offset = extract_field (FLD_imm5, code, 0);
1567 return aarch64_ext_sve_addr_reg_imm (self, info, code, offset);
1570 /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>{, <modifier> {#<msz>}}],
1571 where <modifier> is given by KIND and where <msz> is a 2-bit unsigned
1572 number. fields[0] specifies the base register field and fields[1]
1573 specifies the offset register field. */
1575 aarch64_ext_sve_addr_zz (const aarch64_operand *self, aarch64_opnd_info *info,
1576 aarch64_insn code, enum aarch64_modifier_kind kind)
1578 info->addr.base_regno = extract_field (self->fields[0], code, 0);
1579 info->addr.offset.regno = extract_field (self->fields[1], code, 0);
1580 info->addr.offset.is_reg = TRUE;
1581 info->addr.writeback = FALSE;
1582 info->addr.preind = TRUE;
1583 info->shifter.kind = kind;
1584 info->shifter.amount = extract_field (FLD_SVE_msz, code, 0);
1585 info->shifter.operator_present = (kind != AARCH64_MOD_LSL
1586 || info->shifter.amount != 0);
1587 info->shifter.amount_present = (info->shifter.amount != 0);
1591 /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>{, LSL #<msz>}], where
1592 <msz> is a 2-bit unsigned number. fields[0] specifies the base register
1593 field and fields[1] specifies the offset register field. */
1595 aarch64_ext_sve_addr_zz_lsl (const aarch64_operand *self,
1596 aarch64_opnd_info *info, aarch64_insn code,
1597 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1598 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1600 return aarch64_ext_sve_addr_zz (self, info, code, AARCH64_MOD_LSL);
1603 /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>, SXTW {#<msz>}], where
1604 <msz> is a 2-bit unsigned number. fields[0] specifies the base register
1605 field and fields[1] specifies the offset register field. */
1607 aarch64_ext_sve_addr_zz_sxtw (const aarch64_operand *self,
1608 aarch64_opnd_info *info, aarch64_insn code,
1609 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1610 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1612 return aarch64_ext_sve_addr_zz (self, info, code, AARCH64_MOD_SXTW);
1615 /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>, UXTW {#<msz>}], where
1616 <msz> is a 2-bit unsigned number. fields[0] specifies the base register
1617 field and fields[1] specifies the offset register field. */
1619 aarch64_ext_sve_addr_zz_uxtw (const aarch64_operand *self,
1620 aarch64_opnd_info *info, aarch64_insn code,
1621 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1622 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1624 return aarch64_ext_sve_addr_zz (self, info, code, AARCH64_MOD_UXTW);
1627 /* Finish decoding an SVE arithmetic immediate, given that INFO already
1628 has the raw field value and that the low 8 bits decode to VALUE. */
1630 decode_sve_aimm (aarch64_opnd_info *info, int64_t value)
1632 info->shifter.kind = AARCH64_MOD_LSL;
1633 info->shifter.amount = 0;
1634 if (info->imm.value & 0x100)
1637 /* Decode 0x100 as #0, LSL #8. */
1638 info->shifter.amount = 8;
1642 info->shifter.operator_present = (info->shifter.amount != 0);
1643 info->shifter.amount_present = (info->shifter.amount != 0);
1644 info->imm.value = value;
1648 /* Decode an SVE ADD/SUB immediate. */
1650 aarch64_ext_sve_aimm (const aarch64_operand *self,
1651 aarch64_opnd_info *info, const aarch64_insn code,
1652 const aarch64_inst *inst,
1653 aarch64_operand_error *errors)
1655 return (aarch64_ext_imm (self, info, code, inst, errors)
1656 && decode_sve_aimm (info, (uint8_t) info->imm.value));
1659 /* Decode an SVE CPY/DUP immediate. */
1661 aarch64_ext_sve_asimm (const aarch64_operand *self,
1662 aarch64_opnd_info *info, const aarch64_insn code,
1663 const aarch64_inst *inst,
1664 aarch64_operand_error *errors)
1666 return (aarch64_ext_imm (self, info, code, inst, errors)
1667 && decode_sve_aimm (info, (int8_t) info->imm.value));
1670 /* Decode a single-bit immediate that selects between #0.5 and #1.0.
1671 The fields array specifies which field to use. */
1673 aarch64_ext_sve_float_half_one (const aarch64_operand *self,
1674 aarch64_opnd_info *info, aarch64_insn code,
1675 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1676 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1678 if (extract_field (self->fields[0], code, 0))
1679 info->imm.value = 0x3f800000;
1681 info->imm.value = 0x3f000000;
1682 info->imm.is_fp = TRUE;
1686 /* Decode a single-bit immediate that selects between #0.5 and #2.0.
1687 The fields array specifies which field to use. */
1689 aarch64_ext_sve_float_half_two (const aarch64_operand *self,
1690 aarch64_opnd_info *info, aarch64_insn code,
1691 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1692 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1694 if (extract_field (self->fields[0], code, 0))
1695 info->imm.value = 0x40000000;
1697 info->imm.value = 0x3f000000;
1698 info->imm.is_fp = TRUE;
1702 /* Decode a single-bit immediate that selects between #0.0 and #1.0.
1703 The fields array specifies which field to use. */
1705 aarch64_ext_sve_float_zero_one (const aarch64_operand *self,
1706 aarch64_opnd_info *info, aarch64_insn code,
1707 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1708 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1710 if (extract_field (self->fields[0], code, 0))
1711 info->imm.value = 0x3f800000;
1713 info->imm.value = 0x0;
1714 info->imm.is_fp = TRUE;
1718 /* Decode Zn[MM], where MM has a 7-bit triangular encoding. The fields
1719 array specifies which field to use for Zn. MM is encoded in the
1720 concatenation of imm5 and SVE_tszh, with imm5 being the less
1721 significant part. */
1723 aarch64_ext_sve_index (const aarch64_operand *self,
1724 aarch64_opnd_info *info, aarch64_insn code,
1725 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1726 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1730 info->reglane.regno = extract_field (self->fields[0], code, 0);
1731 val = extract_fields (code, 0, 2, FLD_SVE_tszh, FLD_imm5);
1732 if ((val & 31) == 0)
1734 while ((val & 1) == 0)
1736 info->reglane.index = val / 2;
1740 /* Decode a logical immediate for the MOV alias of SVE DUPM. */
1742 aarch64_ext_sve_limm_mov (const aarch64_operand *self,
1743 aarch64_opnd_info *info, const aarch64_insn code,
1744 const aarch64_inst *inst,
1745 aarch64_operand_error *errors)
1747 int esize = aarch64_get_qualifier_esize (inst->operands[0].qualifier);
1748 return (aarch64_ext_limm (self, info, code, inst, errors)
1749 && aarch64_sve_dupm_mov_immediate_p (info->imm.value, esize));
1752 /* Decode Zn[MM], where Zn occupies the least-significant part of the field
1753 and where MM occupies the most-significant part. The operand-dependent
1754 value specifies the number of bits in Zn. */
1756 aarch64_ext_sve_quad_index (const aarch64_operand *self,
1757 aarch64_opnd_info *info, aarch64_insn code,
1758 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1759 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1761 unsigned int reg_bits = get_operand_specific_data (self);
1762 unsigned int val = extract_all_fields (self, code);
1763 info->reglane.regno = val & ((1 << reg_bits) - 1);
1764 info->reglane.index = val >> reg_bits;
1768 /* Decode {Zn.<T> - Zm.<T>}. The fields array specifies which field
1769 to use for Zn. The opcode-dependent value specifies the number
1770 of registers in the list. */
1772 aarch64_ext_sve_reglist (const aarch64_operand *self,
1773 aarch64_opnd_info *info, aarch64_insn code,
1774 const aarch64_inst *inst ATTRIBUTE_UNUSED,
1775 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
1777 info->reglist.first_regno = extract_field (self->fields[0], code, 0);
1778 info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
1782 /* Decode <pattern>{, MUL #<amount>}. The fields array specifies which
1783 fields to use for <pattern>. <amount> - 1 is encoded in the SVE_imm4
1786 aarch64_ext_sve_scale (const aarch64_operand *self,
1787 aarch64_opnd_info *info, aarch64_insn code,
1788 const aarch64_inst *inst, aarch64_operand_error *errors)
1792 if (!aarch64_ext_imm (self, info, code, inst, errors))
1794 val = extract_field (FLD_SVE_imm4, code, 0);
1795 info->shifter.kind = AARCH64_MOD_MUL;
1796 info->shifter.amount = val + 1;
1797 info->shifter.operator_present = (val != 0);
1798 info->shifter.amount_present = (val != 0);
1802 /* Return the top set bit in VALUE, which is expected to be relatively
1805 get_top_bit (uint64_t value)
1807 while ((value & -value) != value)
1808 value -= value & -value;
1812 /* Decode an SVE shift-left immediate. */
1814 aarch64_ext_sve_shlimm (const aarch64_operand *self,
1815 aarch64_opnd_info *info, const aarch64_insn code,
1816 const aarch64_inst *inst, aarch64_operand_error *errors)
1818 if (!aarch64_ext_imm (self, info, code, inst, errors)
1819 || info->imm.value == 0)
1822 info->imm.value -= get_top_bit (info->imm.value);
1826 /* Decode an SVE shift-right immediate. */
1828 aarch64_ext_sve_shrimm (const aarch64_operand *self,
1829 aarch64_opnd_info *info, const aarch64_insn code,
1830 const aarch64_inst *inst, aarch64_operand_error *errors)
1832 if (!aarch64_ext_imm (self, info, code, inst, errors)
1833 || info->imm.value == 0)
1836 info->imm.value = get_top_bit (info->imm.value) * 2 - info->imm.value;
1840 /* Bitfields that are commonly used to encode certain operands' information
1841 may be partially used as part of the base opcode in some instructions.
1842 For example, the bit 1 of the field 'size' in
1843 FCVTXN <Vb><d>, <Va><n>
1844 is actually part of the base opcode, while only size<0> is available
1845 for encoding the register type. Another example is the AdvSIMD
1846 instruction ORR (register), in which the field 'size' is also used for
1847 the base opcode, leaving only the field 'Q' available to encode the
1848 vector register arrangement specifier '8B' or '16B'.
1850 This function tries to deduce the qualifier from the value of partially
1851 constrained field(s). Given the VALUE of such a field or fields, the
1852 qualifiers CANDIDATES and the MASK (indicating which bits are valid for
1853 operand encoding), the function returns the matching qualifier or
1854 AARCH64_OPND_QLF_NIL if nothing matches.
1856 N.B. CANDIDATES is a group of possible qualifiers that are valid for
1857 one operand; it has a maximum of AARCH64_MAX_QLF_SEQ_NUM qualifiers and
1858 may end with AARCH64_OPND_QLF_NIL. */
1860 static enum aarch64_opnd_qualifier
1861 get_qualifier_from_partial_encoding (aarch64_insn value,
1862 const enum aarch64_opnd_qualifier* \
1867 DEBUG_TRACE ("enter with value: %d, mask: %d", (int)value, (int)mask);
1868 for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
1870 aarch64_insn standard_value;
1871 if (candidates[i] == AARCH64_OPND_QLF_NIL)
1873 standard_value = aarch64_get_qualifier_standard_value (candidates[i]);
1874 if ((standard_value & mask) == (value & mask))
1875 return candidates[i];
1877 return AARCH64_OPND_QLF_NIL;
1880 /* Given a list of qualifier sequences, return all possible valid qualifiers
1881 for operand IDX in QUALIFIERS.
1882 Assume QUALIFIERS is an array whose length is large enough. */
1885 get_operand_possible_qualifiers (int idx,
1886 const aarch64_opnd_qualifier_seq_t *list,
1887 enum aarch64_opnd_qualifier *qualifiers)
1890 for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
1891 if ((qualifiers[i] = list[i][idx]) == AARCH64_OPND_QLF_NIL)
1895 /* Decode the size Q field for e.g. SHADD.
1896 We tag one operand with the qualifer according to the code;
1897 whether the qualifier is valid for this opcode or not, it is the
1898 duty of the semantic checking. */
1901 decode_sizeq (aarch64_inst *inst)
1904 enum aarch64_opnd_qualifier qualifier;
1906 aarch64_insn value, mask;
1907 enum aarch64_field_kind fld_sz;
1908 enum aarch64_opnd_qualifier candidates[AARCH64_MAX_QLF_SEQ_NUM];
1910 if (inst->opcode->iclass == asisdlse
1911 || inst->opcode->iclass == asisdlsep
1912 || inst->opcode->iclass == asisdlso
1913 || inst->opcode->iclass == asisdlsop)
1914 fld_sz = FLD_vldst_size;
1919 value = extract_fields (code, inst->opcode->mask, 2, fld_sz, FLD_Q);
1920 /* Obtain the info that which bits of fields Q and size are actually
1921 available for operand encoding. Opcodes like FMAXNM and FMLA have
1922 size[1] unavailable. */
1923 mask = extract_fields (~inst->opcode->mask, 0, 2, fld_sz, FLD_Q);
1925 /* The index of the operand we are going to tag a qualifier and the qualifer
1926 itself are reasoned from the value of the size and Q fields and the
1927 possible valid qualifier lists. */
1928 idx = aarch64_select_operand_for_sizeq_field_coding (inst->opcode);
1929 DEBUG_TRACE ("key idx: %d", idx);
1931 /* For most related instruciton, size:Q are fully available for operand
1935 inst->operands[idx].qualifier = get_vreg_qualifier_from_value (value);
1939 get_operand_possible_qualifiers (idx, inst->opcode->qualifiers_list,
1941 #ifdef DEBUG_AARCH64
1945 for (i = 0; candidates[i] != AARCH64_OPND_QLF_NIL
1946 && i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
1947 DEBUG_TRACE ("qualifier %d: %s", i,
1948 aarch64_get_qualifier_name(candidates[i]));
1949 DEBUG_TRACE ("%d, %d", (int)value, (int)mask);
1951 #endif /* DEBUG_AARCH64 */
1953 qualifier = get_qualifier_from_partial_encoding (value, candidates, mask);
1955 if (qualifier == AARCH64_OPND_QLF_NIL)
1958 inst->operands[idx].qualifier = qualifier;
1962 /* Decode size[0]:Q, i.e. bit 22 and bit 30, for
1963 e.g. FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>. */
1966 decode_asimd_fcvt (aarch64_inst *inst)
1968 aarch64_field field = {0, 0};
1970 enum aarch64_opnd_qualifier qualifier;
1972 gen_sub_field (FLD_size, 0, 1, &field);
1973 value = extract_field_2 (&field, inst->value, 0);
1974 qualifier = value == 0 ? AARCH64_OPND_QLF_V_4S
1975 : AARCH64_OPND_QLF_V_2D;
1976 switch (inst->opcode->op)
1980 /* FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>. */
1981 inst->operands[1].qualifier = qualifier;
1985 /* FCVTL<Q> <Vd>.<Ta>, <Vn>.<Tb>. */
1986 inst->operands[0].qualifier = qualifier;
1996 /* Decode size[0], i.e. bit 22, for
1997 e.g. FCVTXN <Vb><d>, <Va><n>. */
2000 decode_asisd_fcvtxn (aarch64_inst *inst)
2002 aarch64_field field = {0, 0};
2003 gen_sub_field (FLD_size, 0, 1, &field);
2004 if (!extract_field_2 (&field, inst->value, 0))
2006 inst->operands[0].qualifier = AARCH64_OPND_QLF_S_S;
2010 /* Decode the 'opc' field for e.g. FCVT <Dd>, <Sn>. */
2012 decode_fcvt (aarch64_inst *inst)
2014 enum aarch64_opnd_qualifier qualifier;
2016 const aarch64_field field = {15, 2};
2019 value = extract_field_2 (&field, inst->value, 0);
2022 case 0: qualifier = AARCH64_OPND_QLF_S_S; break;
2023 case 1: qualifier = AARCH64_OPND_QLF_S_D; break;
2024 case 3: qualifier = AARCH64_OPND_QLF_S_H; break;
2027 inst->operands[0].qualifier = qualifier;
2032 /* Do miscellaneous decodings that are not common enough to be driven by
2036 do_misc_decoding (aarch64_inst *inst)
2039 switch (inst->opcode->op)
2042 return decode_fcvt (inst);
2048 return decode_asimd_fcvt (inst);
2051 return decode_asisd_fcvtxn (inst);
2055 value = extract_field (FLD_SVE_Pn, inst->value, 0);
2056 return (value == extract_field (FLD_SVE_Pm, inst->value, 0)
2057 && value == extract_field (FLD_SVE_Pg4_10, inst->value, 0));
2060 return (extract_field (FLD_SVE_Zd, inst->value, 0)
2061 == extract_field (FLD_SVE_Zm_16, inst->value, 0));
2064 /* Index must be zero. */
2065 value = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_imm5);
2066 return value > 0 && value <= 16 && value == (value & -value);
2069 return (extract_field (FLD_SVE_Zn, inst->value, 0)
2070 == extract_field (FLD_SVE_Zm_16, inst->value, 0));
2073 /* Index must be nonzero. */
2074 value = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_imm5);
2075 return value > 0 && value != (value & -value);
2078 return (extract_field (FLD_SVE_Pd, inst->value, 0)
2079 == extract_field (FLD_SVE_Pm, inst->value, 0));
2081 case OP_MOVZS_P_P_P:
2083 return (extract_field (FLD_SVE_Pn, inst->value, 0)
2084 == extract_field (FLD_SVE_Pm, inst->value, 0));
2086 case OP_NOTS_P_P_P_Z:
2087 case OP_NOT_P_P_P_Z:
2088 return (extract_field (FLD_SVE_Pm, inst->value, 0)
2089 == extract_field (FLD_SVE_Pg4_10, inst->value, 0));
2096 /* Opcodes that have fields shared by multiple operands are usually flagged
2097 with flags. In this function, we detect such flags, decode the related
2098 field(s) and store the information in one of the related operands. The
2099 'one' operand is not any operand but one of the operands that can
2100 accommadate all the information that has been decoded. */
2103 do_special_decoding (aarch64_inst *inst)
2107 /* Condition for truly conditional executed instructions, e.g. b.cond. */
2108 if (inst->opcode->flags & F_COND)
2110 value = extract_field (FLD_cond2, inst->value, 0);
2111 inst->cond = get_cond_from_value (value);
2114 if (inst->opcode->flags & F_SF)
2116 idx = select_operand_for_sf_field_coding (inst->opcode);
2117 value = extract_field (FLD_sf, inst->value, 0);
2118 inst->operands[idx].qualifier = get_greg_qualifier_from_value (value);
2119 if ((inst->opcode->flags & F_N)
2120 && extract_field (FLD_N, inst->value, 0) != value)
2124 if (inst->opcode->flags & F_LSE_SZ)
2126 idx = select_operand_for_sf_field_coding (inst->opcode);
2127 value = extract_field (FLD_lse_sz, inst->value, 0);
2128 inst->operands[idx].qualifier = get_greg_qualifier_from_value (value);
2130 /* size:Q fields. */
2131 if (inst->opcode->flags & F_SIZEQ)
2132 return decode_sizeq (inst);
2134 if (inst->opcode->flags & F_FPTYPE)
2136 idx = select_operand_for_fptype_field_coding (inst->opcode);
2137 value = extract_field (FLD_type, inst->value, 0);
2140 case 0: inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_S; break;
2141 case 1: inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_D; break;
2142 case 3: inst->operands[idx].qualifier = AARCH64_OPND_QLF_S_H; break;
2147 if (inst->opcode->flags & F_SSIZE)
2149 /* N.B. some opcodes like FCMGT <V><d>, <V><n>, #0 have the size[1] as part
2150 of the base opcode. */
2152 enum aarch64_opnd_qualifier candidates[AARCH64_MAX_QLF_SEQ_NUM];
2153 idx = select_operand_for_scalar_size_field_coding (inst->opcode);
2154 value = extract_field (FLD_size, inst->value, inst->opcode->mask);
2155 mask = extract_field (FLD_size, ~inst->opcode->mask, 0);
2156 /* For most related instruciton, the 'size' field is fully available for
2157 operand encoding. */
2159 inst->operands[idx].qualifier = get_sreg_qualifier_from_value (value);
2162 get_operand_possible_qualifiers (idx, inst->opcode->qualifiers_list,
2164 inst->operands[idx].qualifier
2165 = get_qualifier_from_partial_encoding (value, candidates, mask);
2169 if (inst->opcode->flags & F_T)
2171 /* Num of consecutive '0's on the right side of imm5<3:0>. */
2174 assert (aarch64_get_operand_class (inst->opcode->operands[0])
2175 == AARCH64_OPND_CLASS_SIMD_REG);
2186 val = extract_field (FLD_imm5, inst->value, 0);
2187 while ((val & 0x1) == 0 && ++num <= 3)
2191 Q = (unsigned) extract_field (FLD_Q, inst->value, inst->opcode->mask);
2192 inst->operands[0].qualifier =
2193 get_vreg_qualifier_from_value ((num << 1) | Q);
2196 if (inst->opcode->flags & F_GPRSIZE_IN_Q)
2198 /* Use Rt to encode in the case of e.g.
2199 STXP <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}]. */
2200 idx = aarch64_operand_index (inst->opcode->operands, AARCH64_OPND_Rt);
2203 /* Otherwise use the result operand, which has to be a integer
2205 assert (aarch64_get_operand_class (inst->opcode->operands[0])
2206 == AARCH64_OPND_CLASS_INT_REG);
2209 assert (idx == 0 || idx == 1);
2210 value = extract_field (FLD_Q, inst->value, 0);
2211 inst->operands[idx].qualifier = get_greg_qualifier_from_value (value);
2214 if (inst->opcode->flags & F_LDS_SIZE)
2216 aarch64_field field = {0, 0};
2217 assert (aarch64_get_operand_class (inst->opcode->operands[0])
2218 == AARCH64_OPND_CLASS_INT_REG);
2219 gen_sub_field (FLD_opc, 0, 1, &field);
2220 value = extract_field_2 (&field, inst->value, 0);
2221 inst->operands[0].qualifier
2222 = value ? AARCH64_OPND_QLF_W : AARCH64_OPND_QLF_X;
2225 /* Miscellaneous decoding; done as the last step. */
2226 if (inst->opcode->flags & F_MISC)
2227 return do_misc_decoding (inst);
2232 /* Converters converting a real opcode instruction to its alias form. */
2234 /* ROR <Wd>, <Ws>, #<shift>
2236 EXTR <Wd>, <Ws>, <Ws>, #<shift>. */
2238 convert_extr_to_ror (aarch64_inst *inst)
2240 if (inst->operands[1].reg.regno == inst->operands[2].reg.regno)
2242 copy_operand_info (inst, 2, 3);
2243 inst->operands[3].type = AARCH64_OPND_NIL;
2249 /* UXTL<Q> <Vd>.<Ta>, <Vn>.<Tb>
2251 USHLL<Q> <Vd>.<Ta>, <Vn>.<Tb>, #0. */
2253 convert_shll_to_xtl (aarch64_inst *inst)
2255 if (inst->operands[2].imm.value == 0)
2257 inst->operands[2].type = AARCH64_OPND_NIL;
2264 UBFM <Xd>, <Xn>, #<shift>, #63.
2266 LSR <Xd>, <Xn>, #<shift>. */
2268 convert_bfm_to_sr (aarch64_inst *inst)
2272 imms = inst->operands[3].imm.value;
2273 val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 31 : 63;
2276 inst->operands[3].type = AARCH64_OPND_NIL;
2283 /* Convert MOV to ORR. */
2285 convert_orr_to_mov (aarch64_inst *inst)
2287 /* MOV <Vd>.<T>, <Vn>.<T>
2289 ORR <Vd>.<T>, <Vn>.<T>, <Vn>.<T>. */
2290 if (inst->operands[1].reg.regno == inst->operands[2].reg.regno)
2292 inst->operands[2].type = AARCH64_OPND_NIL;
2298 /* When <imms> >= <immr>, the instruction written:
2299 SBFX <Xd>, <Xn>, #<lsb>, #<width>
2301 SBFM <Xd>, <Xn>, #<lsb>, #(<lsb>+<width>-1). */
2304 convert_bfm_to_bfx (aarch64_inst *inst)
2308 immr = inst->operands[2].imm.value;
2309 imms = inst->operands[3].imm.value;
2313 inst->operands[2].imm.value = lsb;
2314 inst->operands[3].imm.value = imms + 1 - lsb;
2315 /* The two opcodes have different qualifiers for
2316 the immediate operands; reset to help the checking. */
2317 reset_operand_qualifier (inst, 2);
2318 reset_operand_qualifier (inst, 3);
2325 /* When <imms> < <immr>, the instruction written:
2326 SBFIZ <Xd>, <Xn>, #<lsb>, #<width>
2328 SBFM <Xd>, <Xn>, #((64-<lsb>)&0x3f), #(<width>-1). */
2331 convert_bfm_to_bfi (aarch64_inst *inst)
2333 int64_t immr, imms, val;
2335 immr = inst->operands[2].imm.value;
2336 imms = inst->operands[3].imm.value;
2337 val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 32 : 64;
2340 inst->operands[2].imm.value = (val - immr) & (val - 1);
2341 inst->operands[3].imm.value = imms + 1;
2342 /* The two opcodes have different qualifiers for
2343 the immediate operands; reset to help the checking. */
2344 reset_operand_qualifier (inst, 2);
2345 reset_operand_qualifier (inst, 3);
2352 /* The instruction written:
2353 BFC <Xd>, #<lsb>, #<width>
2355 BFM <Xd>, XZR, #((64-<lsb>)&0x3f), #(<width>-1). */
2358 convert_bfm_to_bfc (aarch64_inst *inst)
2360 int64_t immr, imms, val;
2362 /* Should have been assured by the base opcode value. */
2363 assert (inst->operands[1].reg.regno == 0x1f);
2365 immr = inst->operands[2].imm.value;
2366 imms = inst->operands[3].imm.value;
2367 val = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 32 : 64;
2370 /* Drop XZR from the second operand. */
2371 copy_operand_info (inst, 1, 2);
2372 copy_operand_info (inst, 2, 3);
2373 inst->operands[3].type = AARCH64_OPND_NIL;
2375 /* Recalculate the immediates. */
2376 inst->operands[1].imm.value = (val - immr) & (val - 1);
2377 inst->operands[2].imm.value = imms + 1;
2379 /* The two opcodes have different qualifiers for the operands; reset to
2380 help the checking. */
2381 reset_operand_qualifier (inst, 1);
2382 reset_operand_qualifier (inst, 2);
2383 reset_operand_qualifier (inst, 3);
2391 /* The instruction written:
2392 LSL <Xd>, <Xn>, #<shift>
2394 UBFM <Xd>, <Xn>, #((64-<shift>)&0x3f), #(63-<shift>). */
2397 convert_ubfm_to_lsl (aarch64_inst *inst)
2399 int64_t immr = inst->operands[2].imm.value;
2400 int64_t imms = inst->operands[3].imm.value;
2402 = inst->operands[2].qualifier == AARCH64_OPND_QLF_imm_0_31 ? 31 : 63;
2404 if ((immr == 0 && imms == val) || immr == imms + 1)
2406 inst->operands[3].type = AARCH64_OPND_NIL;
2407 inst->operands[2].imm.value = val - imms;
2414 /* CINC <Wd>, <Wn>, <cond>
2416 CSINC <Wd>, <Wn>, <Wn>, invert(<cond>)
2417 where <cond> is not AL or NV. */
2420 convert_from_csel (aarch64_inst *inst)
2422 if (inst->operands[1].reg.regno == inst->operands[2].reg.regno
2423 && (inst->operands[3].cond->value & 0xe) != 0xe)
2425 copy_operand_info (inst, 2, 3);
2426 inst->operands[2].cond = get_inverted_cond (inst->operands[3].cond);
2427 inst->operands[3].type = AARCH64_OPND_NIL;
2433 /* CSET <Wd>, <cond>
2435 CSINC <Wd>, WZR, WZR, invert(<cond>)
2436 where <cond> is not AL or NV. */
2439 convert_csinc_to_cset (aarch64_inst *inst)
2441 if (inst->operands[1].reg.regno == 0x1f
2442 && inst->operands[2].reg.regno == 0x1f
2443 && (inst->operands[3].cond->value & 0xe) != 0xe)
2445 copy_operand_info (inst, 1, 3);
2446 inst->operands[1].cond = get_inverted_cond (inst->operands[3].cond);
2447 inst->operands[3].type = AARCH64_OPND_NIL;
2448 inst->operands[2].type = AARCH64_OPND_NIL;
2456 MOVZ <Wd>, #<imm16>, LSL #<shift>.
2458 A disassembler may output ORR, MOVZ and MOVN as a MOV mnemonic, except when
2459 ORR has an immediate that could be generated by a MOVZ or MOVN instruction,
2460 or where a MOVN has an immediate that could be encoded by MOVZ, or where
2461 MOVZ/MOVN #0 have a shift amount other than LSL #0, in which case the
2462 machine-instruction mnemonic must be used. */
2465 convert_movewide_to_mov (aarch64_inst *inst)
2467 uint64_t value = inst->operands[1].imm.value;
2468 /* MOVZ/MOVN #0 have a shift amount other than LSL #0. */
2469 if (value == 0 && inst->operands[1].shifter.amount != 0)
2471 inst->operands[1].type = AARCH64_OPND_IMM_MOV;
2472 inst->operands[1].shifter.kind = AARCH64_MOD_NONE;
2473 value <<= inst->operands[1].shifter.amount;
2474 /* As an alias convertor, it has to be clear that the INST->OPCODE
2475 is the opcode of the real instruction. */
2476 if (inst->opcode->op == OP_MOVN)
2478 int is32 = inst->operands[0].qualifier == AARCH64_OPND_QLF_W;
2480 /* A MOVN has an immediate that could be encoded by MOVZ. */
2481 if (aarch64_wide_constant_p (value, is32, NULL))
2484 inst->operands[1].imm.value = value;
2485 inst->operands[1].shifter.amount = 0;
2491 ORR <Wd>, WZR, #<imm>.
2493 A disassembler may output ORR, MOVZ and MOVN as a MOV mnemonic, except when
2494 ORR has an immediate that could be generated by a MOVZ or MOVN instruction,
2495 or where a MOVN has an immediate that could be encoded by MOVZ, or where
2496 MOVZ/MOVN #0 have a shift amount other than LSL #0, in which case the
2497 machine-instruction mnemonic must be used. */
2500 convert_movebitmask_to_mov (aarch64_inst *inst)
2505 /* Should have been assured by the base opcode value. */
2506 assert (inst->operands[1].reg.regno == 0x1f);
2507 copy_operand_info (inst, 1, 2);
2508 is32 = inst->operands[0].qualifier == AARCH64_OPND_QLF_W;
2509 inst->operands[1].type = AARCH64_OPND_IMM_MOV;
2510 value = inst->operands[1].imm.value;
2511 /* ORR has an immediate that could be generated by a MOVZ or MOVN
2513 if (inst->operands[0].reg.regno != 0x1f
2514 && (aarch64_wide_constant_p (value, is32, NULL)
2515 || aarch64_wide_constant_p (~value, is32, NULL)))
2518 inst->operands[2].type = AARCH64_OPND_NIL;
2522 /* Some alias opcodes are disassembled by being converted from their real-form.
2523 N.B. INST->OPCODE is the real opcode rather than the alias. */
2526 convert_to_alias (aarch64_inst *inst, const aarch64_opcode *alias)
2532 return convert_bfm_to_sr (inst);
2534 return convert_ubfm_to_lsl (inst);
2538 return convert_from_csel (inst);
2541 return convert_csinc_to_cset (inst);
2545 return convert_bfm_to_bfx (inst);
2549 return convert_bfm_to_bfi (inst);
2551 return convert_bfm_to_bfc (inst);
2553 return convert_orr_to_mov (inst);
2554 case OP_MOV_IMM_WIDE:
2555 case OP_MOV_IMM_WIDEN:
2556 return convert_movewide_to_mov (inst);
2557 case OP_MOV_IMM_LOG:
2558 return convert_movebitmask_to_mov (inst);
2560 return convert_extr_to_ror (inst);
2565 return convert_shll_to_xtl (inst);
2572 aarch64_opcode_decode (const aarch64_opcode *, const aarch64_insn,
2573 aarch64_inst *, int, aarch64_operand_error *errors);
2575 /* Given the instruction information in *INST, check if the instruction has
2576 any alias form that can be used to represent *INST. If the answer is yes,
2577 update *INST to be in the form of the determined alias. */
2579 /* In the opcode description table, the following flags are used in opcode
2580 entries to help establish the relations between the real and alias opcodes:
2582 F_ALIAS: opcode is an alias
2583 F_HAS_ALIAS: opcode has alias(es)
2586 F_P3: Disassembly preference priority 1-3 (the larger the
2587 higher). If nothing is specified, it is the priority
2588 0 by default, i.e. the lowest priority.
2590 Although the relation between the machine and the alias instructions are not
2591 explicitly described, it can be easily determined from the base opcode
2592 values, masks and the flags F_ALIAS and F_HAS_ALIAS in their opcode
2593 description entries:
2595 The mask of an alias opcode must be equal to or a super-set (i.e. more
2596 constrained) of that of the aliased opcode; so is the base opcode value.
2598 if (opcode_has_alias (real) && alias_opcode_p (opcode)
2599 && (opcode->mask & real->mask) == real->mask
2600 && (real->mask & opcode->opcode) == (real->mask & real->opcode))
2601 then OPCODE is an alias of, and only of, the REAL instruction
2603 The alias relationship is forced flat-structured to keep related algorithm
2604 simple; an opcode entry cannot be flagged with both F_ALIAS and F_HAS_ALIAS.
2606 During the disassembling, the decoding decision tree (in
2607 opcodes/aarch64-dis-2.c) always returns an machine instruction opcode entry;
2608 if the decoding of such a machine instruction succeeds (and -Mno-aliases is
2609 not specified), the disassembler will check whether there is any alias
2610 instruction exists for this real instruction. If there is, the disassembler
2611 will try to disassemble the 32-bit binary again using the alias's rule, or
2612 try to convert the IR to the form of the alias. In the case of the multiple
2613 aliases, the aliases are tried one by one from the highest priority
2614 (currently the flag F_P3) to the lowest priority (no priority flag), and the
2615 first succeeds first adopted.
2617 You may ask why there is a need for the conversion of IR from one form to
2618 another in handling certain aliases. This is because on one hand it avoids
2619 adding more operand code to handle unusual encoding/decoding; on other
2620 hand, during the disassembling, the conversion is an effective approach to
2621 check the condition of an alias (as an alias may be adopted only if certain
2622 conditions are met).
2624 In order to speed up the alias opcode lookup, aarch64-gen has preprocessed
2625 aarch64_opcode_table and generated aarch64_find_alias_opcode and
2626 aarch64_find_next_alias_opcode (in opcodes/aarch64-dis-2.c) to help. */
2629 determine_disassembling_preference (struct aarch64_inst *inst,
2630 aarch64_operand_error *errors)
2632 const aarch64_opcode *opcode;
2633 const aarch64_opcode *alias;
2635 opcode = inst->opcode;
2637 /* This opcode does not have an alias, so use itself. */
2638 if (!opcode_has_alias (opcode))
2641 alias = aarch64_find_alias_opcode (opcode);
2644 #ifdef DEBUG_AARCH64
2647 const aarch64_opcode *tmp = alias;
2648 printf ("#### LIST orderd: ");
2651 printf ("%s, ", tmp->name);
2652 tmp = aarch64_find_next_alias_opcode (tmp);
2656 #endif /* DEBUG_AARCH64 */
2658 for (; alias; alias = aarch64_find_next_alias_opcode (alias))
2660 DEBUG_TRACE ("try %s", alias->name);
2661 assert (alias_opcode_p (alias) || opcode_has_alias (opcode));
2663 /* An alias can be a pseudo opcode which will never be used in the
2664 disassembly, e.g. BIC logical immediate is such a pseudo opcode
2666 if (pseudo_opcode_p (alias))
2668 DEBUG_TRACE ("skip pseudo %s", alias->name);
2672 if ((inst->value & alias->mask) != alias->opcode)
2674 DEBUG_TRACE ("skip %s as base opcode not match", alias->name);
2677 /* No need to do any complicated transformation on operands, if the alias
2678 opcode does not have any operand. */
2679 if (aarch64_num_of_operands (alias) == 0 && alias->opcode == inst->value)
2681 DEBUG_TRACE ("succeed with 0-operand opcode %s", alias->name);
2682 aarch64_replace_opcode (inst, alias);
2685 if (alias->flags & F_CONV)
2688 memcpy (©, inst, sizeof (aarch64_inst));
2689 /* ALIAS is the preference as long as the instruction can be
2690 successfully converted to the form of ALIAS. */
2691 if (convert_to_alias (©, alias) == 1)
2693 aarch64_replace_opcode (©, alias);
2694 assert (aarch64_match_operands_constraint (©, NULL));
2695 DEBUG_TRACE ("succeed with %s via conversion", alias->name);
2696 memcpy (inst, ©, sizeof (aarch64_inst));
2702 /* Directly decode the alias opcode. */
2704 memset (&temp, '\0', sizeof (aarch64_inst));
2705 if (aarch64_opcode_decode (alias, inst->value, &temp, 1, errors) == 1)
2707 DEBUG_TRACE ("succeed with %s via direct decoding", alias->name);
2708 memcpy (inst, &temp, sizeof (aarch64_inst));
2715 /* Some instructions (including all SVE ones) use the instruction class
2716 to describe how a qualifiers_list index is represented in the instruction
2717 encoding. If INST is such an instruction, decode the appropriate fields
2718 and fill in the operand qualifiers accordingly. Return true if no
2719 problems are found. */
2722 aarch64_decode_variant_using_iclass (aarch64_inst *inst)
2727 switch (inst->opcode->iclass)
2730 variant = extract_fields (inst->value, 0, 2, FLD_size, FLD_SVE_M_14);
2734 i = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_imm5);
2737 while ((i & 1) == 0)
2745 /* Pick the smallest applicable element size. */
2746 if ((inst->value & 0x20600) == 0x600)
2748 else if ((inst->value & 0x20400) == 0x400)
2750 else if ((inst->value & 0x20000) == 0)
2757 /* sve_misc instructions have only a single variant. */
2761 variant = extract_fields (inst->value, 0, 2, FLD_size, FLD_SVE_M_16);
2765 variant = extract_field (FLD_SVE_M_4, inst->value, 0);
2768 case sve_shift_pred:
2769 i = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_SVE_tszl_8);
2780 case sve_shift_unpred:
2781 i = extract_fields (inst->value, 0, 2, FLD_SVE_tszh, FLD_SVE_tszl_19);
2785 variant = extract_field (FLD_size, inst->value, 0);
2791 variant = extract_field (FLD_size, inst->value, 0);
2795 i = extract_field (FLD_size, inst->value, 0);
2802 variant = extract_field (FLD_SVE_sz, inst->value, 0);
2806 /* No mapping between instruction class and qualifiers. */
2810 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2811 inst->operands[i].qualifier = inst->opcode->qualifiers_list[variant][i];
2814 /* Decode the CODE according to OPCODE; fill INST. Return 0 if the decoding
2815 fails, which meanes that CODE is not an instruction of OPCODE; otherwise
2818 If OPCODE has alias(es) and NOALIASES_P is 0, an alias opcode may be
2819 determined and used to disassemble CODE; this is done just before the
2823 aarch64_opcode_decode (const aarch64_opcode *opcode, const aarch64_insn code,
2824 aarch64_inst *inst, int noaliases_p,
2825 aarch64_operand_error *errors)
2829 DEBUG_TRACE ("enter with %s", opcode->name);
2831 assert (opcode && inst);
2834 memset (inst, '\0', sizeof (aarch64_inst));
2836 /* Check the base opcode. */
2837 if ((code & opcode->mask) != (opcode->opcode & opcode->mask))
2839 DEBUG_TRACE ("base opcode match FAIL");
2843 inst->opcode = opcode;
2846 /* Assign operand codes and indexes. */
2847 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2849 if (opcode->operands[i] == AARCH64_OPND_NIL)
2851 inst->operands[i].type = opcode->operands[i];
2852 inst->operands[i].idx = i;
2855 /* Call the opcode decoder indicated by flags. */
2856 if (opcode_has_special_coder (opcode) && do_special_decoding (inst) == 0)
2858 DEBUG_TRACE ("opcode flag-based decoder FAIL");
2862 /* Possibly use the instruction class to determine the correct
2864 if (!aarch64_decode_variant_using_iclass (inst))
2866 DEBUG_TRACE ("iclass-based decoder FAIL");
2870 /* Call operand decoders. */
2871 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2873 const aarch64_operand *opnd;
2874 enum aarch64_opnd type;
2876 type = opcode->operands[i];
2877 if (type == AARCH64_OPND_NIL)
2879 opnd = &aarch64_operands[type];
2880 if (operand_has_extractor (opnd)
2881 && (! aarch64_extract_operand (opnd, &inst->operands[i], code, inst,
2884 DEBUG_TRACE ("operand decoder FAIL at operand %d", i);
2889 /* If the opcode has a verifier, then check it now. */
2890 if (opcode->verifier && ! opcode->verifier (opcode, code))
2892 DEBUG_TRACE ("operand verifier FAIL");
2896 /* Match the qualifiers. */
2897 if (aarch64_match_operands_constraint (inst, NULL) == 1)
2899 /* Arriving here, the CODE has been determined as a valid instruction
2900 of OPCODE and *INST has been filled with information of this OPCODE
2901 instruction. Before the return, check if the instruction has any
2902 alias and should be disassembled in the form of its alias instead.
2903 If the answer is yes, *INST will be updated. */
2905 determine_disassembling_preference (inst, errors);
2906 DEBUG_TRACE ("SUCCESS");
2911 DEBUG_TRACE ("constraint matching FAIL");
2918 /* This does some user-friendly fix-up to *INST. It is currently focus on
2919 the adjustment of qualifiers to help the printed instruction
2920 recognized/understood more easily. */
2923 user_friendly_fixup (aarch64_inst *inst)
2925 switch (inst->opcode->iclass)
2928 /* TBNZ Xn|Wn, #uimm6, label
2929 Test and Branch Not Zero: conditionally jumps to label if bit number
2930 uimm6 in register Xn is not zero. The bit number implies the width of
2931 the register, which may be written and should be disassembled as Wn if
2932 uimm is less than 32. Limited to a branch offset range of +/- 32KiB.
2934 if (inst->operands[1].imm.value < 32)
2935 inst->operands[0].qualifier = AARCH64_OPND_QLF_W;
2941 /* Decode INSN and fill in *INST the instruction information. An alias
2942 opcode may be filled in *INSN if NOALIASES_P is FALSE. Return zero on
2946 aarch64_decode_insn (aarch64_insn insn, aarch64_inst *inst,
2947 bfd_boolean noaliases_p,
2948 aarch64_operand_error *errors)
2950 const aarch64_opcode *opcode = aarch64_opcode_lookup (insn);
2952 #ifdef DEBUG_AARCH64
2955 const aarch64_opcode *tmp = opcode;
2957 DEBUG_TRACE ("opcode lookup:");
2960 aarch64_verbose (" %s", tmp->name);
2961 tmp = aarch64_find_next_opcode (tmp);
2964 #endif /* DEBUG_AARCH64 */
2966 /* A list of opcodes may have been found, as aarch64_opcode_lookup cannot
2967 distinguish some opcodes, e.g. SSHR and MOVI, which almost share the same
2968 opcode field and value, apart from the difference that one of them has an
2969 extra field as part of the opcode, but such a field is used for operand
2970 encoding in other opcode(s) ('immh' in the case of the example). */
2971 while (opcode != NULL)
2973 /* But only one opcode can be decoded successfully for, as the
2974 decoding routine will check the constraint carefully. */
2975 if (aarch64_opcode_decode (opcode, insn, inst, noaliases_p, errors) == 1)
2977 opcode = aarch64_find_next_opcode (opcode);
2983 /* Print operands. */
2986 print_operands (bfd_vma pc, const aarch64_opcode *opcode,
2987 const aarch64_opnd_info *opnds, struct disassemble_info *info)
2989 int i, pcrel_p, num_printed;
2991 for (i = 0, num_printed = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2994 /* We regard the opcode operand info more, however we also look into
2995 the inst->operands to support the disassembling of the optional
2997 The two operand code should be the same in all cases, apart from
2998 when the operand can be optional. */
2999 if (opcode->operands[i] == AARCH64_OPND_NIL
3000 || opnds[i].type == AARCH64_OPND_NIL)
3003 /* Generate the operand string in STR. */
3004 aarch64_print_operand (str, sizeof (str), pc, opcode, opnds, i, &pcrel_p,
3005 &info->target, ¬es);
3007 /* Print the delimiter (taking account of omitted operand(s)). */
3009 (*info->fprintf_func) (info->stream, "%s",
3010 num_printed++ == 0 ? "\t" : ", ");
3012 /* Print the operand. */
3014 (*info->print_address_func) (info->target, info);
3016 (*info->fprintf_func) (info->stream, "%s", str);
3019 if (notes && !no_notes)
3020 (*info->fprintf_func) (info->stream, "\t; note: %s", notes);
3023 /* Set NAME to a copy of INST's mnemonic with the "." suffix removed. */
3026 remove_dot_suffix (char *name, const aarch64_inst *inst)
3031 ptr = strchr (inst->opcode->name, '.');
3032 assert (ptr && inst->cond);
3033 len = ptr - inst->opcode->name;
3035 strncpy (name, inst->opcode->name, len);
3039 /* Print the instruction mnemonic name. */
3042 print_mnemonic_name (const aarch64_inst *inst, struct disassemble_info *info)
3044 if (inst->opcode->flags & F_COND)
3046 /* For instructions that are truly conditionally executed, e.g. b.cond,
3047 prepare the full mnemonic name with the corresponding condition
3051 remove_dot_suffix (name, inst);
3052 (*info->fprintf_func) (info->stream, "%s.%s", name, inst->cond->names[0]);
3055 (*info->fprintf_func) (info->stream, "%s", inst->opcode->name);
3058 /* Decide whether we need to print a comment after the operands of
3059 instruction INST. */
3062 print_comment (const aarch64_inst *inst, struct disassemble_info *info)
3064 if (inst->opcode->flags & F_COND)
3067 unsigned int i, num_conds;
3069 remove_dot_suffix (name, inst);
3070 num_conds = ARRAY_SIZE (inst->cond->names);
3071 for (i = 1; i < num_conds && inst->cond->names[i]; ++i)
3072 (*info->fprintf_func) (info->stream, "%s %s.%s",
3073 i == 1 ? " //" : ",",
3074 name, inst->cond->names[i]);
3078 /* Print the instruction according to *INST. */
3081 print_aarch64_insn (bfd_vma pc, const aarch64_inst *inst,
3082 struct disassemble_info *info)
3084 print_mnemonic_name (inst, info);
3085 print_operands (pc, inst->opcode, inst->operands, info);
3086 print_comment (inst, info);
3089 /* Entry-point of the instruction disassembler and printer. */
3092 print_insn_aarch64_word (bfd_vma pc,
3094 struct disassemble_info *info,
3095 aarch64_operand_error *errors)
3097 static const char *err_msg[6] =
3100 [-ERR_UND] = "undefined",
3101 [-ERR_UNP] = "unpredictable",
3108 info->insn_info_valid = 1;
3109 info->branch_delay_insns = 0;
3110 info->data_size = 0;
3114 if (info->flags & INSN_HAS_RELOC)
3115 /* If the instruction has a reloc associated with it, then
3116 the offset field in the instruction will actually be the
3117 addend for the reloc. (If we are using REL type relocs).
3118 In such cases, we can ignore the pc when computing
3119 addresses, since the addend is not currently pc-relative. */
3122 ret = aarch64_decode_insn (word, &inst, no_aliases, errors);
3124 if (((word >> 21) & 0x3ff) == 1)
3126 /* RESERVED for ALES. */
3127 assert (ret != ERR_OK);
3136 /* Handle undefined instructions. */
3137 info->insn_type = dis_noninsn;
3138 (*info->fprintf_func) (info->stream,".inst\t0x%08x ; %s",
3139 word, err_msg[-ret]);
3142 user_friendly_fixup (&inst);
3143 print_aarch64_insn (pc, &inst, info);
3150 /* Disallow mapping symbols ($x, $d etc) from
3151 being displayed in symbol relative addresses. */
3154 aarch64_symbol_is_valid (asymbol * sym,
3155 struct disassemble_info * info ATTRIBUTE_UNUSED)
3162 name = bfd_asymbol_name (sym);
3166 || (name[1] != 'x' && name[1] != 'd')
3167 || (name[2] != '\0' && name[2] != '.'));
3170 /* Print data bytes on INFO->STREAM. */
3173 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
3175 struct disassemble_info *info,
3176 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
3178 switch (info->bytes_per_chunk)
3181 info->fprintf_func (info->stream, ".byte\t0x%02x", word);
3184 info->fprintf_func (info->stream, ".short\t0x%04x", word);
3187 info->fprintf_func (info->stream, ".word\t0x%08x", word);
3194 /* Try to infer the code or data type from a symbol.
3195 Returns nonzero if *MAP_TYPE was set. */
3198 get_sym_code_type (struct disassemble_info *info, int n,
3199 enum map_type *map_type)
3201 elf_symbol_type *es;
3205 /* If the symbol is in a different section, ignore it. */
3206 if (info->section != NULL && info->section != info->symtab[n]->section)
3209 es = *(elf_symbol_type **)(info->symtab + n);
3210 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
3212 /* If the symbol has function type then use that. */
3213 if (type == STT_FUNC)
3215 *map_type = MAP_INSN;
3219 /* Check for mapping symbols. */
3220 name = bfd_asymbol_name(info->symtab[n]);
3222 && (name[1] == 'x' || name[1] == 'd')
3223 && (name[2] == '\0' || name[2] == '.'))
3225 *map_type = (name[1] == 'x' ? MAP_INSN : MAP_DATA);
3232 /* Entry-point of the AArch64 disassembler. */
3235 print_insn_aarch64 (bfd_vma pc,
3236 struct disassemble_info *info)
3238 bfd_byte buffer[INSNLEN];
3240 void (*printer) (bfd_vma, uint32_t, struct disassemble_info *,
3241 aarch64_operand_error *);
3242 bfd_boolean found = FALSE;
3243 unsigned int size = 4;
3245 aarch64_operand_error errors;
3247 if (info->disassembler_options)
3249 set_default_aarch64_dis_options (info);
3251 parse_aarch64_dis_options (info->disassembler_options);
3253 /* To avoid repeated parsing of these options, we remove them here. */
3254 info->disassembler_options = NULL;
3257 /* Aarch64 instructions are always little-endian */
3258 info->endian_code = BFD_ENDIAN_LITTLE;
3260 /* First check the full symtab for a mapping symbol, even if there
3261 are no usable non-mapping symbols for this address. */
3262 if (info->symtab_size != 0
3263 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
3265 enum map_type type = MAP_INSN;
3270 if (pc <= last_mapping_addr)
3271 last_mapping_sym = -1;
3273 /* Start scanning at the start of the function, or wherever
3274 we finished last time. */
3275 n = info->symtab_pos + 1;
3276 if (n < last_mapping_sym)
3277 n = last_mapping_sym;
3279 /* Scan up to the location being disassembled. */
3280 for (; n < info->symtab_size; n++)
3282 addr = bfd_asymbol_value (info->symtab[n]);
3285 if (get_sym_code_type (info, n, &type))
3294 n = info->symtab_pos;
3295 if (n < last_mapping_sym)
3296 n = last_mapping_sym;
3298 /* No mapping symbol found at this address. Look backwards
3299 for a preceeding one. */
3302 if (get_sym_code_type (info, n, &type))
3311 last_mapping_sym = last_sym;
3314 /* Look a little bit ahead to see if we should print out
3315 less than four bytes of data. If there's a symbol,
3316 mapping or otherwise, after two bytes then don't
3318 if (last_type == MAP_DATA)
3320 size = 4 - (pc & 3);
3321 for (n = last_sym + 1; n < info->symtab_size; n++)
3323 addr = bfd_asymbol_value (info->symtab[n]);
3326 if (addr - pc < size)
3331 /* If the next symbol is after three bytes, we need to
3332 print only part of the data, so that we can use either
3335 size = (pc & 1) ? 1 : 2;
3339 if (last_type == MAP_DATA)
3341 /* size was set above. */
3342 info->bytes_per_chunk = size;
3343 info->display_endian = info->endian;
3344 printer = print_insn_data;
3348 info->bytes_per_chunk = size = INSNLEN;
3349 info->display_endian = info->endian_code;
3350 printer = print_insn_aarch64_word;
3353 status = (*info->read_memory_func) (pc, buffer, size, info);
3356 (*info->memory_error_func) (status, pc, info);
3360 data = bfd_get_bits (buffer, size * 8,
3361 info->display_endian == BFD_ENDIAN_BIG);
3363 (*printer) (pc, data, info, &errors);
3369 print_aarch64_disassembler_options (FILE *stream)
3371 fprintf (stream, _("\n\
3372 The following AARCH64 specific disassembler options are supported for use\n\
3373 with the -M switch (multiple options should be separated by commas):\n"));
3375 fprintf (stream, _("\n\
3376 no-aliases Don't print instruction aliases.\n"));
3378 fprintf (stream, _("\n\
3379 aliases Do print instruction aliases.\n"));
3381 fprintf (stream, _("\n\
3382 no-notes Don't print instruction notes.\n"));
3384 fprintf (stream, _("\n\
3385 notes Do print instruction notes.\n"));
3387 #ifdef DEBUG_AARCH64
3388 fprintf (stream, _("\n\
3389 debug_dump Temp switch for debug trace.\n"));
3390 #endif /* DEBUG_AARCH64 */
3392 fprintf (stream, _("\n"));