1 /* aarch64-dis.c -- AArch64 disassembler.
2 Copyright (C) 2009-2020 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"
31 /* Cached mapping symbol state. */
38 static aarch64_feature_set arch_variant
; /* See select_aarch64_variant. */
39 static enum map_type last_type
;
40 static int last_mapping_sym
= -1;
41 static bfd_vma last_stop_offset
= 0;
42 static bfd_vma last_mapping_addr
= 0;
45 static int no_aliases
= 0; /* If set disassemble as most general inst. */
46 \fstatic int no_notes
= 1; /* If set do not print disassemble notes in the
47 output as comments. */
49 /* Currently active instruction sequence. */
50 static aarch64_instr_sequence insn_sequence
;
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 uint64_t
183 sign_extend (aarch64_insn value
, unsigned i
)
189 sign
= (uint64_t) 1 << i
;
190 return ((ret
& (sign
+ sign
- 1)) ^ sign
) - sign
;
193 /* N.B. the following inline helpfer functions create a dependency on the
194 order of operand qualifier enumerators. */
196 /* Given VALUE, return qualifier for a general purpose register. */
197 static inline enum aarch64_opnd_qualifier
198 get_greg_qualifier_from_value (aarch64_insn value
)
200 enum aarch64_opnd_qualifier qualifier
= AARCH64_OPND_QLF_W
+ value
;
202 && aarch64_get_qualifier_standard_value (qualifier
) == value
);
206 /* Given VALUE, return qualifier for a vector register. This does not support
207 decoding instructions that accept the 2H vector type. */
209 static inline enum aarch64_opnd_qualifier
210 get_vreg_qualifier_from_value (aarch64_insn value
)
212 enum aarch64_opnd_qualifier qualifier
= AARCH64_OPND_QLF_V_8B
+ value
;
214 /* Instructions using vector type 2H should not call this function. Skip over
216 if (qualifier
>= AARCH64_OPND_QLF_V_2H
)
220 && aarch64_get_qualifier_standard_value (qualifier
) == value
);
224 /* Given VALUE, return qualifier for an FP or AdvSIMD scalar register. */
225 static inline enum aarch64_opnd_qualifier
226 get_sreg_qualifier_from_value (aarch64_insn value
)
228 enum aarch64_opnd_qualifier qualifier
= AARCH64_OPND_QLF_S_B
+ value
;
231 && aarch64_get_qualifier_standard_value (qualifier
) == value
);
235 /* Given the instruction in *INST which is probably half way through the
236 decoding and our caller wants to know the expected qualifier for operand
237 I. Return such a qualifier if we can establish it; otherwise return
238 AARCH64_OPND_QLF_NIL. */
240 static aarch64_opnd_qualifier_t
241 get_expected_qualifier (const aarch64_inst
*inst
, int i
)
243 aarch64_opnd_qualifier_seq_t qualifiers
;
244 /* Should not be called if the qualifier is known. */
245 assert (inst
->operands
[i
].qualifier
== AARCH64_OPND_QLF_NIL
);
246 if (aarch64_find_best_match (inst
, inst
->opcode
->qualifiers_list
,
248 return qualifiers
[i
];
250 return AARCH64_OPND_QLF_NIL
;
253 /* Operand extractors. */
256 aarch64_ext_none (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
257 aarch64_opnd_info
*info ATTRIBUTE_UNUSED
,
258 const aarch64_insn code ATTRIBUTE_UNUSED
,
259 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
260 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
266 aarch64_ext_regno (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
267 const aarch64_insn code
,
268 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
269 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
271 info
->reg
.regno
= extract_field (self
->fields
[0], code
, 0);
276 aarch64_ext_regno_pair (const aarch64_operand
*self ATTRIBUTE_UNUSED
, aarch64_opnd_info
*info
,
277 const aarch64_insn code ATTRIBUTE_UNUSED
,
278 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
279 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
281 assert (info
->idx
== 1
283 info
->reg
.regno
= inst
->operands
[info
->idx
- 1].reg
.regno
+ 1;
287 /* e.g. IC <ic_op>{, <Xt>}. */
289 aarch64_ext_regrt_sysins (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
290 const aarch64_insn code
,
291 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
292 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
294 info
->reg
.regno
= extract_field (self
->fields
[0], code
, 0);
295 assert (info
->idx
== 1
296 && (aarch64_get_operand_class (inst
->operands
[0].type
)
297 == AARCH64_OPND_CLASS_SYSTEM
));
298 /* This will make the constraint checking happy and more importantly will
299 help the disassembler determine whether this operand is optional or
301 info
->present
= aarch64_sys_ins_reg_has_xt (inst
->operands
[0].sysins_op
);
306 /* e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]. */
308 aarch64_ext_reglane (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
309 const aarch64_insn code
,
310 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
311 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
314 info
->reglane
.regno
= extract_field (self
->fields
[0], code
,
317 /* Index and/or type. */
318 if (inst
->opcode
->iclass
== asisdone
319 || inst
->opcode
->iclass
== asimdins
)
321 if (info
->type
== AARCH64_OPND_En
322 && inst
->opcode
->operands
[0] == AARCH64_OPND_Ed
)
325 /* index2 for e.g. INS <Vd>.<Ts>[<index1>], <Vn>.<Ts>[<index2>]. */
326 assert (info
->idx
== 1); /* Vn */
327 aarch64_insn value
= extract_field (FLD_imm4
, code
, 0);
328 /* Depend on AARCH64_OPND_Ed to determine the qualifier. */
329 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
330 shift
= get_logsz (aarch64_get_qualifier_esize (info
->qualifier
));
331 info
->reglane
.index
= value
>> shift
;
335 /* index and type for e.g. DUP <V><d>, <Vn>.<T>[<index>].
343 aarch64_insn value
= extract_field (FLD_imm5
, code
, 0);
344 while (++pos
<= 3 && (value
& 0x1) == 0)
348 info
->qualifier
= get_sreg_qualifier_from_value (pos
);
349 info
->reglane
.index
= (unsigned) (value
>> 1);
352 else if (inst
->opcode
->iclass
== dotproduct
)
354 /* Need information in other operand(s) to help decoding. */
355 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
356 switch (info
->qualifier
)
358 case AARCH64_OPND_QLF_S_4B
:
359 case AARCH64_OPND_QLF_S_2H
:
361 info
->reglane
.index
= extract_fields (code
, 0, 2, FLD_H
, FLD_L
);
362 info
->reglane
.regno
&= 0x1f;
368 else if (inst
->opcode
->iclass
== cryptosm3
)
370 /* index for e.g. SM3TT2A <Vd>.4S, <Vn>.4S, <Vm>S[<imm2>]. */
371 info
->reglane
.index
= extract_field (FLD_SM3_imm2
, code
, 0);
375 /* Index only for e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
376 or SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]. */
378 /* Need information in other operand(s) to help decoding. */
379 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
380 switch (info
->qualifier
)
382 case AARCH64_OPND_QLF_S_H
:
383 if (info
->type
== AARCH64_OPND_Em16
)
386 info
->reglane
.index
= extract_fields (code
, 0, 3, FLD_H
, FLD_L
,
388 info
->reglane
.regno
&= 0xf;
393 info
->reglane
.index
= extract_fields (code
, 0, 2, FLD_H
, FLD_L
);
396 case AARCH64_OPND_QLF_S_S
:
398 info
->reglane
.index
= extract_fields (code
, 0, 2, FLD_H
, FLD_L
);
400 case AARCH64_OPND_QLF_S_D
:
402 info
->reglane
.index
= extract_field (FLD_H
, code
, 0);
408 if (inst
->opcode
->op
== OP_FCMLA_ELEM
409 && info
->qualifier
!= AARCH64_OPND_QLF_S_H
)
411 /* Complex operand takes two elements. */
412 if (info
->reglane
.index
& 1)
414 info
->reglane
.index
/= 2;
422 aarch64_ext_reglist (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
423 const aarch64_insn code
,
424 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
425 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
428 info
->reglist
.first_regno
= extract_field (self
->fields
[0], code
, 0);
430 info
->reglist
.num_regs
= extract_field (FLD_len
, code
, 0) + 1;
434 /* Decode Rt and opcode fields of Vt in AdvSIMD load/store instructions. */
436 aarch64_ext_ldst_reglist (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
437 aarch64_opnd_info
*info
, const aarch64_insn code
,
438 const aarch64_inst
*inst
,
439 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
442 /* Number of elements in each structure to be loaded/stored. */
443 unsigned expected_num
= get_opcode_dependent_value (inst
->opcode
);
447 unsigned is_reserved
;
449 unsigned num_elements
;
465 info
->reglist
.first_regno
= extract_field (FLD_Rt
, code
, 0);
467 value
= extract_field (FLD_opcode
, code
, 0);
468 /* PR 21595: Check for a bogus value. */
469 if (value
>= ARRAY_SIZE (data
))
471 if (expected_num
!= data
[value
].num_elements
|| data
[value
].is_reserved
)
473 info
->reglist
.num_regs
= data
[value
].num_regs
;
478 /* Decode Rt and S fields of Vt in AdvSIMD load single structure to all
479 lanes instructions. */
481 aarch64_ext_ldst_reglist_r (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
482 aarch64_opnd_info
*info
, const aarch64_insn code
,
483 const aarch64_inst
*inst
,
484 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
489 info
->reglist
.first_regno
= extract_field (FLD_Rt
, code
, 0);
491 value
= extract_field (FLD_S
, code
, 0);
493 /* Number of registers is equal to the number of elements in
494 each structure to be loaded/stored. */
495 info
->reglist
.num_regs
= get_opcode_dependent_value (inst
->opcode
);
496 assert (info
->reglist
.num_regs
>= 1 && info
->reglist
.num_regs
<= 4);
498 /* Except when it is LD1R. */
499 if (info
->reglist
.num_regs
== 1 && value
== (aarch64_insn
) 1)
500 info
->reglist
.num_regs
= 2;
505 /* Decode Q, opcode<2:1>, S, size and Rt fields of Vt in AdvSIMD
506 load/store single element instructions. */
508 aarch64_ext_ldst_elemlist (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
509 aarch64_opnd_info
*info
, const aarch64_insn code
,
510 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
511 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
513 aarch64_field field
= {0, 0};
514 aarch64_insn QSsize
; /* fields Q:S:size. */
515 aarch64_insn opcodeh2
; /* opcode<2:1> */
518 info
->reglist
.first_regno
= extract_field (FLD_Rt
, code
, 0);
520 /* Decode the index, opcode<2:1> and size. */
521 gen_sub_field (FLD_asisdlso_opcode
, 1, 2, &field
);
522 opcodeh2
= extract_field_2 (&field
, code
, 0);
523 QSsize
= extract_fields (code
, 0, 3, FLD_Q
, FLD_S
, FLD_vldst_size
);
527 info
->qualifier
= AARCH64_OPND_QLF_S_B
;
528 /* Index encoded in "Q:S:size". */
529 info
->reglist
.index
= QSsize
;
535 info
->qualifier
= AARCH64_OPND_QLF_S_H
;
536 /* Index encoded in "Q:S:size<1>". */
537 info
->reglist
.index
= QSsize
>> 1;
540 if ((QSsize
>> 1) & 0x1)
543 if ((QSsize
& 0x1) == 0)
545 info
->qualifier
= AARCH64_OPND_QLF_S_S
;
546 /* Index encoded in "Q:S". */
547 info
->reglist
.index
= QSsize
>> 2;
551 if (extract_field (FLD_S
, code
, 0))
554 info
->qualifier
= AARCH64_OPND_QLF_S_D
;
555 /* Index encoded in "Q". */
556 info
->reglist
.index
= QSsize
>> 3;
563 info
->reglist
.has_index
= 1;
564 info
->reglist
.num_regs
= 0;
565 /* Number of registers is equal to the number of elements in
566 each structure to be loaded/stored. */
567 info
->reglist
.num_regs
= get_opcode_dependent_value (inst
->opcode
);
568 assert (info
->reglist
.num_regs
>= 1 && info
->reglist
.num_regs
<= 4);
573 /* Decode fields immh:immb and/or Q for e.g.
574 SSHR <Vd>.<T>, <Vn>.<T>, #<shift>
575 or SSHR <V><d>, <V><n>, #<shift>. */
578 aarch64_ext_advsimd_imm_shift (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
579 aarch64_opnd_info
*info
, const aarch64_insn code
,
580 const aarch64_inst
*inst
,
581 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
584 aarch64_insn Q
, imm
, immh
;
585 enum aarch64_insn_class iclass
= inst
->opcode
->iclass
;
587 immh
= extract_field (FLD_immh
, code
, 0);
590 imm
= extract_fields (code
, 0, 2, FLD_immh
, FLD_immb
);
592 /* Get highest set bit in immh. */
593 while (--pos
>= 0 && (immh
& 0x8) == 0)
596 assert ((iclass
== asimdshf
|| iclass
== asisdshf
)
597 && (info
->type
== AARCH64_OPND_IMM_VLSR
598 || info
->type
== AARCH64_OPND_IMM_VLSL
));
600 if (iclass
== asimdshf
)
602 Q
= extract_field (FLD_Q
, code
, 0);
604 0000 x SEE AdvSIMD modified immediate
614 get_vreg_qualifier_from_value ((pos
<< 1) | (int) Q
);
617 info
->qualifier
= get_sreg_qualifier_from_value (pos
);
619 if (info
->type
== AARCH64_OPND_IMM_VLSR
)
621 0000 SEE AdvSIMD modified immediate
622 0001 (16-UInt(immh:immb))
623 001x (32-UInt(immh:immb))
624 01xx (64-UInt(immh:immb))
625 1xxx (128-UInt(immh:immb)) */
626 info
->imm
.value
= (16 << pos
) - imm
;
630 0000 SEE AdvSIMD modified immediate
631 0001 (UInt(immh:immb)-8)
632 001x (UInt(immh:immb)-16)
633 01xx (UInt(immh:immb)-32)
634 1xxx (UInt(immh:immb)-64) */
635 info
->imm
.value
= imm
- (8 << pos
);
640 /* Decode shift immediate for e.g. sshr (imm). */
642 aarch64_ext_shll_imm (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
643 aarch64_opnd_info
*info
, const aarch64_insn code
,
644 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
645 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
649 val
= extract_field (FLD_size
, code
, 0);
652 case 0: imm
= 8; break;
653 case 1: imm
= 16; break;
654 case 2: imm
= 32; break;
655 default: return FALSE
;
657 info
->imm
.value
= imm
;
661 /* Decode imm for e.g. BFM <Wd>, <Wn>, #<immr>, #<imms>.
662 value in the field(s) will be extracted as unsigned immediate value. */
664 aarch64_ext_imm (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
665 const aarch64_insn code
,
666 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
667 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
671 imm
= extract_all_fields (self
, code
);
673 if (operand_need_sign_extension (self
))
674 imm
= sign_extend (imm
, get_operand_fields_width (self
) - 1);
676 if (operand_need_shift_by_two (self
))
678 else if (operand_need_shift_by_four (self
))
681 if (info
->type
== AARCH64_OPND_ADDR_ADRP
)
684 info
->imm
.value
= imm
;
688 /* Decode imm and its shifter for e.g. MOVZ <Wd>, #<imm16>{, LSL #<shift>}. */
690 aarch64_ext_imm_half (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
691 const aarch64_insn code
,
692 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
693 aarch64_operand_error
*errors
)
695 aarch64_ext_imm (self
, info
, code
, inst
, errors
);
696 info
->shifter
.kind
= AARCH64_MOD_LSL
;
697 info
->shifter
.amount
= extract_field (FLD_hw
, code
, 0) << 4;
701 /* Decode cmode and "a:b:c:d:e:f:g:h" for e.g.
702 MOVI <Vd>.<T>, #<imm8> {, LSL #<amount>}. */
704 aarch64_ext_advsimd_imm_modified (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
705 aarch64_opnd_info
*info
,
706 const aarch64_insn code
,
707 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
708 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
711 enum aarch64_opnd_qualifier opnd0_qualifier
= inst
->operands
[0].qualifier
;
712 aarch64_field field
= {0, 0};
714 assert (info
->idx
== 1);
716 if (info
->type
== AARCH64_OPND_SIMD_FPIMM
)
719 /* a:b:c:d:e:f:g:h */
720 imm
= extract_fields (code
, 0, 2, FLD_abc
, FLD_defgh
);
721 if (!info
->imm
.is_fp
&& aarch64_get_qualifier_esize (opnd0_qualifier
) == 8)
723 /* Either MOVI <Dd>, #<imm>
724 or MOVI <Vd>.2D, #<imm>.
725 <imm> is a 64-bit immediate
726 'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh',
727 encoded in "a:b:c:d:e:f:g:h". */
729 unsigned abcdefgh
= imm
;
730 for (imm
= 0ull, i
= 0; i
< 8; i
++)
731 if (((abcdefgh
>> i
) & 0x1) != 0)
732 imm
|= 0xffull
<< (8 * i
);
734 info
->imm
.value
= imm
;
737 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
738 switch (info
->qualifier
)
740 case AARCH64_OPND_QLF_NIL
:
742 info
->shifter
.kind
= AARCH64_MOD_NONE
;
744 case AARCH64_OPND_QLF_LSL
:
746 info
->shifter
.kind
= AARCH64_MOD_LSL
;
747 switch (aarch64_get_qualifier_esize (opnd0_qualifier
))
749 case 4: gen_sub_field (FLD_cmode
, 1, 2, &field
); break; /* per word */
750 case 2: gen_sub_field (FLD_cmode
, 1, 1, &field
); break; /* per half */
751 case 1: gen_sub_field (FLD_cmode
, 1, 0, &field
); break; /* per byte */
752 default: assert (0); return FALSE
;
754 /* 00: 0; 01: 8; 10:16; 11:24. */
755 info
->shifter
.amount
= extract_field_2 (&field
, code
, 0) << 3;
757 case AARCH64_OPND_QLF_MSL
:
759 info
->shifter
.kind
= AARCH64_MOD_MSL
;
760 gen_sub_field (FLD_cmode
, 0, 1, &field
); /* per word */
761 info
->shifter
.amount
= extract_field_2 (&field
, code
, 0) ? 16 : 8;
771 /* Decode an 8-bit floating-point immediate. */
773 aarch64_ext_fpimm (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
774 const aarch64_insn code
,
775 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
776 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
778 info
->imm
.value
= extract_all_fields (self
, code
);
783 /* Decode a 1-bit rotate immediate (#90 or #270). */
785 aarch64_ext_imm_rotate1 (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
786 const aarch64_insn code
,
787 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
788 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
790 uint64_t rot
= extract_field (self
->fields
[0], code
, 0);
792 info
->imm
.value
= rot
* 180 + 90;
796 /* Decode a 2-bit rotate immediate (#0, #90, #180 or #270). */
798 aarch64_ext_imm_rotate2 (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
799 const aarch64_insn code
,
800 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
801 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
803 uint64_t rot
= extract_field (self
->fields
[0], code
, 0);
805 info
->imm
.value
= rot
* 90;
809 /* Decode scale for e.g. SCVTF <Dd>, <Wn>, #<fbits>. */
811 aarch64_ext_fbits (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
812 aarch64_opnd_info
*info
, const aarch64_insn code
,
813 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
814 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
816 info
->imm
.value
= 64- extract_field (FLD_scale
, code
, 0);
820 /* Decode arithmetic immediate for e.g.
821 SUBS <Wd>, <Wn|WSP>, #<imm> {, <shift>}. */
823 aarch64_ext_aimm (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
824 aarch64_opnd_info
*info
, const aarch64_insn code
,
825 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
826 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
830 info
->shifter
.kind
= AARCH64_MOD_LSL
;
832 value
= extract_field (FLD_shift
, code
, 0);
835 info
->shifter
.amount
= value
? 12 : 0;
836 /* imm12 (unsigned) */
837 info
->imm
.value
= extract_field (FLD_imm12
, code
, 0);
842 /* Return true if VALUE is a valid logical immediate encoding, storing the
843 decoded value in *RESULT if so. ESIZE is the number of bytes in the
844 decoded immediate. */
846 decode_limm (uint32_t esize
, aarch64_insn value
, int64_t *result
)
852 /* value is N:immr:imms. */
854 R
= (value
>> 6) & 0x3f;
855 N
= (value
>> 12) & 0x1;
857 /* The immediate value is S+1 bits to 1, left rotated by SIMDsize - R
858 (in other words, right rotated by R), then replicated. */
862 mask
= 0xffffffffffffffffull
;
868 case 0x00 ... 0x1f: /* 0xxxxx */ simd_size
= 32; break;
869 case 0x20 ... 0x2f: /* 10xxxx */ simd_size
= 16; S
&= 0xf; break;
870 case 0x30 ... 0x37: /* 110xxx */ simd_size
= 8; S
&= 0x7; break;
871 case 0x38 ... 0x3b: /* 1110xx */ simd_size
= 4; S
&= 0x3; break;
872 case 0x3c ... 0x3d: /* 11110x */ simd_size
= 2; S
&= 0x1; break;
873 default: return FALSE
;
875 mask
= (1ull << simd_size
) - 1;
876 /* Top bits are IGNORED. */
880 if (simd_size
> esize
* 8)
883 /* NOTE: if S = simd_size - 1 we get 0xf..f which is rejected. */
884 if (S
== simd_size
- 1)
886 /* S+1 consecutive bits to 1. */
887 /* NOTE: S can't be 63 due to detection above. */
888 imm
= (1ull << (S
+ 1)) - 1;
889 /* Rotate to the left by simd_size - R. */
891 imm
= ((imm
<< (simd_size
- R
)) & mask
) | (imm
>> R
);
892 /* Replicate the value according to SIMD size. */
895 case 2: imm
= (imm
<< 2) | imm
;
897 case 4: imm
= (imm
<< 4) | imm
;
899 case 8: imm
= (imm
<< 8) | imm
;
901 case 16: imm
= (imm
<< 16) | imm
;
903 case 32: imm
= (imm
<< 32) | imm
;
906 default: assert (0); return 0;
909 *result
= imm
& ~((uint64_t) -1 << (esize
* 4) << (esize
* 4));
914 /* Decode a logical immediate for e.g. ORR <Wd|WSP>, <Wn>, #<imm>. */
916 aarch64_ext_limm (const aarch64_operand
*self
,
917 aarch64_opnd_info
*info
, const aarch64_insn code
,
918 const aarch64_inst
*inst
,
919 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
924 value
= extract_fields (code
, 0, 3, self
->fields
[0], self
->fields
[1],
926 esize
= aarch64_get_qualifier_esize (inst
->operands
[0].qualifier
);
927 return decode_limm (esize
, value
, &info
->imm
.value
);
930 /* Decode a logical immediate for the BIC alias of AND (etc.). */
932 aarch64_ext_inv_limm (const aarch64_operand
*self
,
933 aarch64_opnd_info
*info
, const aarch64_insn code
,
934 const aarch64_inst
*inst
,
935 aarch64_operand_error
*errors
)
937 if (!aarch64_ext_limm (self
, info
, code
, inst
, errors
))
939 info
->imm
.value
= ~info
->imm
.value
;
943 /* Decode Ft for e.g. STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]
944 or LDP <Qt1>, <Qt2>, [<Xn|SP>], #<imm>. */
946 aarch64_ext_ft (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
947 aarch64_opnd_info
*info
,
948 const aarch64_insn code
, const aarch64_inst
*inst
,
949 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
954 info
->reg
.regno
= extract_field (FLD_Rt
, code
, 0);
957 value
= extract_field (FLD_ldst_size
, code
, 0);
958 if (inst
->opcode
->iclass
== ldstpair_indexed
959 || inst
->opcode
->iclass
== ldstnapair_offs
960 || inst
->opcode
->iclass
== ldstpair_off
961 || inst
->opcode
->iclass
== loadlit
)
963 enum aarch64_opnd_qualifier qualifier
;
966 case 0: qualifier
= AARCH64_OPND_QLF_S_S
; break;
967 case 1: qualifier
= AARCH64_OPND_QLF_S_D
; break;
968 case 2: qualifier
= AARCH64_OPND_QLF_S_Q
; break;
969 default: return FALSE
;
971 info
->qualifier
= qualifier
;
976 value
= extract_fields (code
, 0, 2, FLD_opc1
, FLD_ldst_size
);
979 info
->qualifier
= get_sreg_qualifier_from_value (value
);
985 /* Decode the address operand for e.g. STXRB <Ws>, <Wt>, [<Xn|SP>{,#0}]. */
987 aarch64_ext_addr_simple (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
988 aarch64_opnd_info
*info
,
990 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
991 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
994 info
->addr
.base_regno
= extract_field (FLD_Rn
, code
, 0);
998 /* Decode the address operand for e.g.
999 stlur <Xt>, [<Xn|SP>{, <amount>}]. */
1001 aarch64_ext_addr_offset (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1002 aarch64_opnd_info
*info
,
1003 aarch64_insn code
, const aarch64_inst
*inst
,
1004 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1006 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
1009 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1012 aarch64_insn imm
= extract_fields (code
, 0, 1, self
->fields
[1]);
1013 info
->addr
.offset
.imm
= sign_extend (imm
, 8);
1014 if (extract_field (self
->fields
[2], code
, 0) == 1) {
1015 info
->addr
.writeback
= 1;
1016 info
->addr
.preind
= 1;
1021 /* Decode the address operand for e.g.
1022 STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]. */
1024 aarch64_ext_addr_regoff (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1025 aarch64_opnd_info
*info
,
1026 aarch64_insn code
, const aarch64_inst
*inst
,
1027 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1029 aarch64_insn S
, value
;
1032 info
->addr
.base_regno
= extract_field (FLD_Rn
, code
, 0);
1034 info
->addr
.offset
.regno
= extract_field (FLD_Rm
, code
, 0);
1036 value
= extract_field (FLD_option
, code
, 0);
1037 info
->shifter
.kind
=
1038 aarch64_get_operand_modifier_from_value (value
, TRUE
/* extend_p */);
1039 /* Fix-up the shifter kind; although the table-driven approach is
1040 efficient, it is slightly inflexible, thus needing this fix-up. */
1041 if (info
->shifter
.kind
== AARCH64_MOD_UXTX
)
1042 info
->shifter
.kind
= AARCH64_MOD_LSL
;
1044 S
= extract_field (FLD_S
, code
, 0);
1047 info
->shifter
.amount
= 0;
1048 info
->shifter
.amount_present
= 0;
1053 /* Need information in other operand(s) to help achieve the decoding
1055 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
1056 /* Get the size of the data element that is accessed, which may be
1057 different from that of the source register size, e.g. in strb/ldrb. */
1058 size
= aarch64_get_qualifier_esize (info
->qualifier
);
1059 info
->shifter
.amount
= get_logsz (size
);
1060 info
->shifter
.amount_present
= 1;
1066 /* Decode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>], #<simm>. */
1068 aarch64_ext_addr_simm (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
1069 aarch64_insn code
, const aarch64_inst
*inst
,
1070 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1073 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
1076 info
->addr
.base_regno
= extract_field (FLD_Rn
, code
, 0);
1077 /* simm (imm9 or imm7) */
1078 imm
= extract_field (self
->fields
[0], code
, 0);
1079 info
->addr
.offset
.imm
= sign_extend (imm
, fields
[self
->fields
[0]].width
- 1);
1080 if (self
->fields
[0] == FLD_imm7
1081 || info
->qualifier
== AARCH64_OPND_QLF_imm_tag
)
1082 /* scaled immediate in ld/st pair instructions. */
1083 info
->addr
.offset
.imm
*= aarch64_get_qualifier_esize (info
->qualifier
);
1085 if (inst
->opcode
->iclass
== ldst_unscaled
1086 || inst
->opcode
->iclass
== ldstnapair_offs
1087 || inst
->opcode
->iclass
== ldstpair_off
1088 || inst
->opcode
->iclass
== ldst_unpriv
)
1089 info
->addr
.writeback
= 0;
1092 /* pre/post- index */
1093 info
->addr
.writeback
= 1;
1094 if (extract_field (self
->fields
[1], code
, 0) == 1)
1095 info
->addr
.preind
= 1;
1097 info
->addr
.postind
= 1;
1103 /* Decode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>{, #<simm>}]. */
1105 aarch64_ext_addr_uimm12 (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
1107 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1108 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1111 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
1112 shift
= get_logsz (aarch64_get_qualifier_esize (info
->qualifier
));
1114 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1116 info
->addr
.offset
.imm
= extract_field (self
->fields
[1], code
, 0) << shift
;
1120 /* Decode the address operand for e.g. LDRAA <Xt>, [<Xn|SP>{, #<simm>}]. */
1122 aarch64_ext_addr_simm10 (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
1124 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1125 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1129 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
1131 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1133 imm
= extract_fields (code
, 0, 2, self
->fields
[1], self
->fields
[2]);
1134 info
->addr
.offset
.imm
= sign_extend (imm
, 9) << 3;
1135 if (extract_field (self
->fields
[3], code
, 0) == 1) {
1136 info
->addr
.writeback
= 1;
1137 info
->addr
.preind
= 1;
1142 /* Decode the address operand for e.g.
1143 LD1 {<Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>}, [<Xn|SP>], <Xm|#<amount>>. */
1145 aarch64_ext_simd_addr_post (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1146 aarch64_opnd_info
*info
,
1147 aarch64_insn code
, const aarch64_inst
*inst
,
1148 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1150 /* The opcode dependent area stores the number of elements in
1151 each structure to be loaded/stored. */
1152 int is_ld1r
= get_opcode_dependent_value (inst
->opcode
) == 1;
1155 info
->addr
.base_regno
= extract_field (FLD_Rn
, code
, 0);
1156 /* Rm | #<amount> */
1157 info
->addr
.offset
.regno
= extract_field (FLD_Rm
, code
, 0);
1158 if (info
->addr
.offset
.regno
== 31)
1160 if (inst
->opcode
->operands
[0] == AARCH64_OPND_LVt_AL
)
1161 /* Special handling of loading single structure to all lane. */
1162 info
->addr
.offset
.imm
= (is_ld1r
? 1
1163 : inst
->operands
[0].reglist
.num_regs
)
1164 * aarch64_get_qualifier_esize (inst
->operands
[0].qualifier
);
1166 info
->addr
.offset
.imm
= inst
->operands
[0].reglist
.num_regs
1167 * aarch64_get_qualifier_esize (inst
->operands
[0].qualifier
)
1168 * aarch64_get_qualifier_nelem (inst
->operands
[0].qualifier
);
1171 info
->addr
.offset
.is_reg
= 1;
1172 info
->addr
.writeback
= 1;
1177 /* Decode the condition operand for e.g. CSEL <Xd>, <Xn>, <Xm>, <cond>. */
1179 aarch64_ext_cond (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1180 aarch64_opnd_info
*info
,
1181 aarch64_insn code
, const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1182 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1186 value
= extract_field (FLD_cond
, code
, 0);
1187 info
->cond
= get_cond_from_value (value
);
1191 /* Decode the system register operand for e.g. MRS <Xt>, <systemreg>. */
1193 aarch64_ext_sysreg (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1194 aarch64_opnd_info
*info
,
1196 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1197 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1199 /* op0:op1:CRn:CRm:op2 */
1200 info
->sysreg
.value
= extract_fields (code
, 0, 5, FLD_op0
, FLD_op1
, FLD_CRn
,
1202 info
->sysreg
.flags
= 0;
1204 /* If a system instruction, check which restrictions should be on the register
1205 value during decoding, these will be enforced then. */
1206 if (inst
->opcode
->iclass
== ic_system
)
1208 /* Check to see if it's read-only, else check if it's write only.
1209 if it's both or unspecified don't care. */
1210 if ((inst
->opcode
->flags
& (F_SYS_READ
| F_SYS_WRITE
)) == F_SYS_READ
)
1211 info
->sysreg
.flags
= F_REG_READ
;
1212 else if ((inst
->opcode
->flags
& (F_SYS_READ
| F_SYS_WRITE
))
1214 info
->sysreg
.flags
= F_REG_WRITE
;
1220 /* Decode the PSTATE field operand for e.g. MSR <pstatefield>, #<imm>. */
1222 aarch64_ext_pstatefield (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1223 aarch64_opnd_info
*info
, aarch64_insn code
,
1224 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1225 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1229 info
->pstatefield
= extract_fields (code
, 0, 2, FLD_op1
, FLD_op2
);
1230 for (i
= 0; aarch64_pstatefields
[i
].name
!= NULL
; ++i
)
1231 if (aarch64_pstatefields
[i
].value
== (aarch64_insn
)info
->pstatefield
)
1233 /* Reserved value in <pstatefield>. */
1237 /* Decode the system instruction op operand for e.g. AT <at_op>, <Xt>. */
1239 aarch64_ext_sysins_op (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1240 aarch64_opnd_info
*info
,
1242 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1243 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1247 const aarch64_sys_ins_reg
*sysins_ops
;
1248 /* op0:op1:CRn:CRm:op2 */
1249 value
= extract_fields (code
, 0, 5,
1250 FLD_op0
, FLD_op1
, FLD_CRn
,
1255 case AARCH64_OPND_SYSREG_AT
: sysins_ops
= aarch64_sys_regs_at
; break;
1256 case AARCH64_OPND_SYSREG_DC
: sysins_ops
= aarch64_sys_regs_dc
; break;
1257 case AARCH64_OPND_SYSREG_IC
: sysins_ops
= aarch64_sys_regs_ic
; break;
1258 case AARCH64_OPND_SYSREG_TLBI
: sysins_ops
= aarch64_sys_regs_tlbi
; break;
1259 case AARCH64_OPND_SYSREG_SR
:
1260 sysins_ops
= aarch64_sys_regs_sr
;
1261 /* Let's remove op2 for rctx. Refer to comments in the definition of
1262 aarch64_sys_regs_sr[]. */
1263 value
= value
& ~(0x7);
1265 default: assert (0); return FALSE
;
1268 for (i
= 0; sysins_ops
[i
].name
!= NULL
; ++i
)
1269 if (sysins_ops
[i
].value
== value
)
1271 info
->sysins_op
= sysins_ops
+ i
;
1272 DEBUG_TRACE ("%s found value: %x, has_xt: %d, i: %d.",
1273 info
->sysins_op
->name
,
1274 (unsigned)info
->sysins_op
->value
,
1275 aarch64_sys_ins_reg_has_xt (info
->sysins_op
), i
);
1282 /* Decode the memory barrier option operand for e.g. DMB <option>|#<imm>. */
1285 aarch64_ext_barrier (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1286 aarch64_opnd_info
*info
,
1288 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1289 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1292 info
->barrier
= aarch64_barrier_options
+ extract_field (FLD_CRm
, code
, 0);
1296 /* Decode the prefetch operation option operand for e.g.
1297 PRFM <prfop>, [<Xn|SP>{, #<pimm>}]. */
1300 aarch64_ext_prfop (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1301 aarch64_opnd_info
*info
,
1302 aarch64_insn code
, const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1303 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1306 info
->prfop
= aarch64_prfops
+ extract_field (FLD_Rt
, code
, 0);
1310 /* Decode the hint number for an alias taking an operand. Set info->hint_option
1311 to the matching name/value pair in aarch64_hint_options. */
1314 aarch64_ext_hint (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1315 aarch64_opnd_info
*info
,
1317 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1318 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1321 unsigned hint_number
;
1324 hint_number
= extract_fields (code
, 0, 2, FLD_CRm
, FLD_op2
);
1326 for (i
= 0; aarch64_hint_options
[i
].name
!= NULL
; i
++)
1328 if (hint_number
== HINT_VAL (aarch64_hint_options
[i
].value
))
1330 info
->hint_option
= &(aarch64_hint_options
[i
]);
1338 /* Decode the extended register operand for e.g.
1339 STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]. */
1341 aarch64_ext_reg_extended (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1342 aarch64_opnd_info
*info
,
1344 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1345 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1350 info
->reg
.regno
= extract_field (FLD_Rm
, code
, 0);
1352 value
= extract_field (FLD_option
, code
, 0);
1353 info
->shifter
.kind
=
1354 aarch64_get_operand_modifier_from_value (value
, TRUE
/* extend_p */);
1356 info
->shifter
.amount
= extract_field (FLD_imm3
, code
, 0);
1358 /* This makes the constraint checking happy. */
1359 info
->shifter
.operator_present
= 1;
1361 /* Assume inst->operands[0].qualifier has been resolved. */
1362 assert (inst
->operands
[0].qualifier
!= AARCH64_OPND_QLF_NIL
);
1363 info
->qualifier
= AARCH64_OPND_QLF_W
;
1364 if (inst
->operands
[0].qualifier
== AARCH64_OPND_QLF_X
1365 && (info
->shifter
.kind
== AARCH64_MOD_UXTX
1366 || info
->shifter
.kind
== AARCH64_MOD_SXTX
))
1367 info
->qualifier
= AARCH64_OPND_QLF_X
;
1372 /* Decode the shifted register operand for e.g.
1373 SUBS <Xd>, <Xn>, <Xm> {, <shift> #<amount>}. */
1375 aarch64_ext_reg_shifted (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1376 aarch64_opnd_info
*info
,
1378 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1379 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1384 info
->reg
.regno
= extract_field (FLD_Rm
, code
, 0);
1386 value
= extract_field (FLD_shift
, code
, 0);
1387 info
->shifter
.kind
=
1388 aarch64_get_operand_modifier_from_value (value
, FALSE
/* extend_p */);
1389 if (info
->shifter
.kind
== AARCH64_MOD_ROR
1390 && inst
->opcode
->iclass
!= log_shift
)
1391 /* ROR is not available for the shifted register operand in arithmetic
1395 info
->shifter
.amount
= extract_field (FLD_imm6
, code
, 0);
1397 /* This makes the constraint checking happy. */
1398 info
->shifter
.operator_present
= 1;
1403 /* Decode an SVE address [<base>, #<offset>*<factor>, MUL VL],
1404 where <offset> is given by the OFFSET parameter and where <factor> is
1405 1 plus SELF's operand-dependent value. fields[0] specifies the field
1406 that holds <base>. */
1408 aarch64_ext_sve_addr_reg_mul_vl (const aarch64_operand
*self
,
1409 aarch64_opnd_info
*info
, aarch64_insn code
,
1412 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1413 info
->addr
.offset
.imm
= offset
* (1 + get_operand_specific_data (self
));
1414 info
->addr
.offset
.is_reg
= FALSE
;
1415 info
->addr
.writeback
= FALSE
;
1416 info
->addr
.preind
= TRUE
;
1418 info
->shifter
.kind
= AARCH64_MOD_MUL_VL
;
1419 info
->shifter
.amount
= 1;
1420 info
->shifter
.operator_present
= (info
->addr
.offset
.imm
!= 0);
1421 info
->shifter
.amount_present
= FALSE
;
1425 /* Decode an SVE address [<base>, #<simm4>*<factor>, MUL VL],
1426 where <simm4> is a 4-bit signed value and where <factor> is 1 plus
1427 SELF's operand-dependent value. fields[0] specifies the field that
1428 holds <base>. <simm4> is encoded in the SVE_imm4 field. */
1430 aarch64_ext_sve_addr_ri_s4xvl (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_imm4
, code
, 0);
1438 offset
= ((offset
+ 8) & 15) - 8;
1439 return aarch64_ext_sve_addr_reg_mul_vl (self
, info
, code
, offset
);
1442 /* Decode an SVE address [<base>, #<simm6>*<factor>, MUL VL],
1443 where <simm6> is a 6-bit signed value and where <factor> is 1 plus
1444 SELF's operand-dependent value. fields[0] specifies the field that
1445 holds <base>. <simm6> is encoded in the SVE_imm6 field. */
1447 aarch64_ext_sve_addr_ri_s6xvl (const aarch64_operand
*self
,
1448 aarch64_opnd_info
*info
, aarch64_insn code
,
1449 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1450 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1454 offset
= extract_field (FLD_SVE_imm6
, code
, 0);
1455 offset
= (((offset
+ 32) & 63) - 32);
1456 return aarch64_ext_sve_addr_reg_mul_vl (self
, info
, code
, offset
);
1459 /* Decode an SVE address [<base>, #<simm9>*<factor>, MUL VL],
1460 where <simm9> is a 9-bit signed value and where <factor> is 1 plus
1461 SELF's operand-dependent value. fields[0] specifies the field that
1462 holds <base>. <simm9> is encoded in the concatenation of the SVE_imm6
1463 and imm3 fields, with imm3 being the less-significant part. */
1465 aarch64_ext_sve_addr_ri_s9xvl (const aarch64_operand
*self
,
1466 aarch64_opnd_info
*info
,
1468 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1469 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1473 offset
= extract_fields (code
, 0, 2, FLD_SVE_imm6
, FLD_imm3
);
1474 offset
= (((offset
+ 256) & 511) - 256);
1475 return aarch64_ext_sve_addr_reg_mul_vl (self
, info
, code
, offset
);
1478 /* Decode an SVE address [<base>, #<offset> << <shift>], where <offset>
1479 is given by the OFFSET parameter and where <shift> is SELF's operand-
1480 dependent value. fields[0] specifies the base register field <base>. */
1482 aarch64_ext_sve_addr_reg_imm (const aarch64_operand
*self
,
1483 aarch64_opnd_info
*info
, aarch64_insn code
,
1486 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1487 info
->addr
.offset
.imm
= offset
* (1 << get_operand_specific_data (self
));
1488 info
->addr
.offset
.is_reg
= FALSE
;
1489 info
->addr
.writeback
= FALSE
;
1490 info
->addr
.preind
= TRUE
;
1491 info
->shifter
.operator_present
= FALSE
;
1492 info
->shifter
.amount_present
= FALSE
;
1496 /* Decode an SVE address [X<n>, #<SVE_imm4> << <shift>], where <SVE_imm4>
1497 is a 4-bit signed number and where <shift> is SELF's operand-dependent
1498 value. fields[0] specifies the base register field. */
1500 aarch64_ext_sve_addr_ri_s4 (const aarch64_operand
*self
,
1501 aarch64_opnd_info
*info
, aarch64_insn code
,
1502 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1503 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1505 int offset
= sign_extend (extract_field (FLD_SVE_imm4
, code
, 0), 3);
1506 return aarch64_ext_sve_addr_reg_imm (self
, info
, code
, offset
);
1509 /* Decode an SVE address [X<n>, #<SVE_imm6> << <shift>], where <SVE_imm6>
1510 is a 6-bit unsigned number and where <shift> is SELF's operand-dependent
1511 value. fields[0] specifies the base register field. */
1513 aarch64_ext_sve_addr_ri_u6 (const aarch64_operand
*self
,
1514 aarch64_opnd_info
*info
, aarch64_insn code
,
1515 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1516 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1518 int offset
= extract_field (FLD_SVE_imm6
, code
, 0);
1519 return aarch64_ext_sve_addr_reg_imm (self
, info
, code
, offset
);
1522 /* Decode an SVE address [X<n>, X<m>{, LSL #<shift>}], where <shift>
1523 is SELF's operand-dependent value. fields[0] specifies the base
1524 register field and fields[1] specifies the offset register field. */
1526 aarch64_ext_sve_addr_rr_lsl (const aarch64_operand
*self
,
1527 aarch64_opnd_info
*info
, aarch64_insn code
,
1528 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1529 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1533 index_regno
= extract_field (self
->fields
[1], code
, 0);
1534 if (index_regno
== 31 && (self
->flags
& OPD_F_NO_ZR
) != 0)
1537 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1538 info
->addr
.offset
.regno
= index_regno
;
1539 info
->addr
.offset
.is_reg
= TRUE
;
1540 info
->addr
.writeback
= FALSE
;
1541 info
->addr
.preind
= TRUE
;
1542 info
->shifter
.kind
= AARCH64_MOD_LSL
;
1543 info
->shifter
.amount
= get_operand_specific_data (self
);
1544 info
->shifter
.operator_present
= (info
->shifter
.amount
!= 0);
1545 info
->shifter
.amount_present
= (info
->shifter
.amount
!= 0);
1549 /* Decode an SVE address [X<n>, Z<m>.<T>, (S|U)XTW {#<shift>}], where
1550 <shift> is SELF's operand-dependent value. fields[0] specifies the
1551 base register field, fields[1] specifies the offset register field and
1552 fields[2] is a single-bit field that selects SXTW over UXTW. */
1554 aarch64_ext_sve_addr_rz_xtw (const aarch64_operand
*self
,
1555 aarch64_opnd_info
*info
, aarch64_insn code
,
1556 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1557 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1559 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1560 info
->addr
.offset
.regno
= extract_field (self
->fields
[1], code
, 0);
1561 info
->addr
.offset
.is_reg
= TRUE
;
1562 info
->addr
.writeback
= FALSE
;
1563 info
->addr
.preind
= TRUE
;
1564 if (extract_field (self
->fields
[2], code
, 0))
1565 info
->shifter
.kind
= AARCH64_MOD_SXTW
;
1567 info
->shifter
.kind
= AARCH64_MOD_UXTW
;
1568 info
->shifter
.amount
= get_operand_specific_data (self
);
1569 info
->shifter
.operator_present
= TRUE
;
1570 info
->shifter
.amount_present
= (info
->shifter
.amount
!= 0);
1574 /* Decode an SVE address [Z<n>.<T>, #<imm5> << <shift>], where <imm5> is a
1575 5-bit unsigned number and where <shift> is SELF's operand-dependent value.
1576 fields[0] specifies the base register field. */
1578 aarch64_ext_sve_addr_zi_u5 (const aarch64_operand
*self
,
1579 aarch64_opnd_info
*info
, aarch64_insn code
,
1580 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1581 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1583 int offset
= extract_field (FLD_imm5
, code
, 0);
1584 return aarch64_ext_sve_addr_reg_imm (self
, info
, code
, offset
);
1587 /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>{, <modifier> {#<msz>}}],
1588 where <modifier> is given by KIND and where <msz> is a 2-bit unsigned
1589 number. fields[0] specifies the base register field and fields[1]
1590 specifies the offset register field. */
1592 aarch64_ext_sve_addr_zz (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
1593 aarch64_insn code
, enum aarch64_modifier_kind kind
)
1595 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1596 info
->addr
.offset
.regno
= extract_field (self
->fields
[1], code
, 0);
1597 info
->addr
.offset
.is_reg
= TRUE
;
1598 info
->addr
.writeback
= FALSE
;
1599 info
->addr
.preind
= TRUE
;
1600 info
->shifter
.kind
= kind
;
1601 info
->shifter
.amount
= extract_field (FLD_SVE_msz
, code
, 0);
1602 info
->shifter
.operator_present
= (kind
!= AARCH64_MOD_LSL
1603 || info
->shifter
.amount
!= 0);
1604 info
->shifter
.amount_present
= (info
->shifter
.amount
!= 0);
1608 /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>{, LSL #<msz>}], where
1609 <msz> is a 2-bit unsigned number. fields[0] specifies the base register
1610 field and fields[1] specifies the offset register field. */
1612 aarch64_ext_sve_addr_zz_lsl (const aarch64_operand
*self
,
1613 aarch64_opnd_info
*info
, aarch64_insn code
,
1614 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1615 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1617 return aarch64_ext_sve_addr_zz (self
, info
, code
, AARCH64_MOD_LSL
);
1620 /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>, SXTW {#<msz>}], where
1621 <msz> is a 2-bit unsigned number. fields[0] specifies the base register
1622 field and fields[1] specifies the offset register field. */
1624 aarch64_ext_sve_addr_zz_sxtw (const aarch64_operand
*self
,
1625 aarch64_opnd_info
*info
, aarch64_insn code
,
1626 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1627 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1629 return aarch64_ext_sve_addr_zz (self
, info
, code
, AARCH64_MOD_SXTW
);
1632 /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>, UXTW {#<msz>}], where
1633 <msz> is a 2-bit unsigned number. fields[0] specifies the base register
1634 field and fields[1] specifies the offset register field. */
1636 aarch64_ext_sve_addr_zz_uxtw (const aarch64_operand
*self
,
1637 aarch64_opnd_info
*info
, aarch64_insn code
,
1638 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1639 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1641 return aarch64_ext_sve_addr_zz (self
, info
, code
, AARCH64_MOD_UXTW
);
1644 /* Finish decoding an SVE arithmetic immediate, given that INFO already
1645 has the raw field value and that the low 8 bits decode to VALUE. */
1647 decode_sve_aimm (aarch64_opnd_info
*info
, int64_t value
)
1649 info
->shifter
.kind
= AARCH64_MOD_LSL
;
1650 info
->shifter
.amount
= 0;
1651 if (info
->imm
.value
& 0x100)
1654 /* Decode 0x100 as #0, LSL #8. */
1655 info
->shifter
.amount
= 8;
1659 info
->shifter
.operator_present
= (info
->shifter
.amount
!= 0);
1660 info
->shifter
.amount_present
= (info
->shifter
.amount
!= 0);
1661 info
->imm
.value
= value
;
1665 /* Decode an SVE ADD/SUB immediate. */
1667 aarch64_ext_sve_aimm (const aarch64_operand
*self
,
1668 aarch64_opnd_info
*info
, const aarch64_insn code
,
1669 const aarch64_inst
*inst
,
1670 aarch64_operand_error
*errors
)
1672 return (aarch64_ext_imm (self
, info
, code
, inst
, errors
)
1673 && decode_sve_aimm (info
, (uint8_t) info
->imm
.value
));
1676 /* Decode an SVE CPY/DUP immediate. */
1678 aarch64_ext_sve_asimm (const aarch64_operand
*self
,
1679 aarch64_opnd_info
*info
, const aarch64_insn code
,
1680 const aarch64_inst
*inst
,
1681 aarch64_operand_error
*errors
)
1683 return (aarch64_ext_imm (self
, info
, code
, inst
, errors
)
1684 && decode_sve_aimm (info
, (int8_t) info
->imm
.value
));
1687 /* Decode a single-bit immediate that selects between #0.5 and #1.0.
1688 The fields array specifies which field to use. */
1690 aarch64_ext_sve_float_half_one (const aarch64_operand
*self
,
1691 aarch64_opnd_info
*info
, aarch64_insn code
,
1692 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1693 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1695 if (extract_field (self
->fields
[0], code
, 0))
1696 info
->imm
.value
= 0x3f800000;
1698 info
->imm
.value
= 0x3f000000;
1699 info
->imm
.is_fp
= TRUE
;
1703 /* Decode a single-bit immediate that selects between #0.5 and #2.0.
1704 The fields array specifies which field to use. */
1706 aarch64_ext_sve_float_half_two (const aarch64_operand
*self
,
1707 aarch64_opnd_info
*info
, aarch64_insn code
,
1708 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1709 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1711 if (extract_field (self
->fields
[0], code
, 0))
1712 info
->imm
.value
= 0x40000000;
1714 info
->imm
.value
= 0x3f000000;
1715 info
->imm
.is_fp
= TRUE
;
1719 /* Decode a single-bit immediate that selects between #0.0 and #1.0.
1720 The fields array specifies which field to use. */
1722 aarch64_ext_sve_float_zero_one (const aarch64_operand
*self
,
1723 aarch64_opnd_info
*info
, aarch64_insn code
,
1724 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1725 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1727 if (extract_field (self
->fields
[0], code
, 0))
1728 info
->imm
.value
= 0x3f800000;
1730 info
->imm
.value
= 0x0;
1731 info
->imm
.is_fp
= TRUE
;
1735 /* Decode Zn[MM], where MM has a 7-bit triangular encoding. The fields
1736 array specifies which field to use for Zn. MM is encoded in the
1737 concatenation of imm5 and SVE_tszh, with imm5 being the less
1738 significant part. */
1740 aarch64_ext_sve_index (const aarch64_operand
*self
,
1741 aarch64_opnd_info
*info
, aarch64_insn code
,
1742 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1743 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1747 info
->reglane
.regno
= extract_field (self
->fields
[0], code
, 0);
1748 val
= extract_fields (code
, 0, 2, FLD_SVE_tszh
, FLD_imm5
);
1749 if ((val
& 31) == 0)
1751 while ((val
& 1) == 0)
1753 info
->reglane
.index
= val
/ 2;
1757 /* Decode a logical immediate for the MOV alias of SVE DUPM. */
1759 aarch64_ext_sve_limm_mov (const aarch64_operand
*self
,
1760 aarch64_opnd_info
*info
, const aarch64_insn code
,
1761 const aarch64_inst
*inst
,
1762 aarch64_operand_error
*errors
)
1764 int esize
= aarch64_get_qualifier_esize (inst
->operands
[0].qualifier
);
1765 return (aarch64_ext_limm (self
, info
, code
, inst
, errors
)
1766 && aarch64_sve_dupm_mov_immediate_p (info
->imm
.value
, esize
));
1769 /* Decode Zn[MM], where Zn occupies the least-significant part of the field
1770 and where MM occupies the most-significant part. The operand-dependent
1771 value specifies the number of bits in Zn. */
1773 aarch64_ext_sve_quad_index (const aarch64_operand
*self
,
1774 aarch64_opnd_info
*info
, aarch64_insn code
,
1775 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1776 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1778 unsigned int reg_bits
= get_operand_specific_data (self
);
1779 unsigned int val
= extract_all_fields (self
, code
);
1780 info
->reglane
.regno
= val
& ((1 << reg_bits
) - 1);
1781 info
->reglane
.index
= val
>> reg_bits
;
1785 /* Decode {Zn.<T> - Zm.<T>}. The fields array specifies which field
1786 to use for Zn. The opcode-dependent value specifies the number
1787 of registers in the list. */
1789 aarch64_ext_sve_reglist (const aarch64_operand
*self
,
1790 aarch64_opnd_info
*info
, aarch64_insn code
,
1791 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1792 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1794 info
->reglist
.first_regno
= extract_field (self
->fields
[0], code
, 0);
1795 info
->reglist
.num_regs
= get_opcode_dependent_value (inst
->opcode
);
1799 /* Decode <pattern>{, MUL #<amount>}. The fields array specifies which
1800 fields to use for <pattern>. <amount> - 1 is encoded in the SVE_imm4
1803 aarch64_ext_sve_scale (const aarch64_operand
*self
,
1804 aarch64_opnd_info
*info
, aarch64_insn code
,
1805 const aarch64_inst
*inst
, aarch64_operand_error
*errors
)
1809 if (!aarch64_ext_imm (self
, info
, code
, inst
, errors
))
1811 val
= extract_field (FLD_SVE_imm4
, code
, 0);
1812 info
->shifter
.kind
= AARCH64_MOD_MUL
;
1813 info
->shifter
.amount
= val
+ 1;
1814 info
->shifter
.operator_present
= (val
!= 0);
1815 info
->shifter
.amount_present
= (val
!= 0);
1819 /* Return the top set bit in VALUE, which is expected to be relatively
1822 get_top_bit (uint64_t value
)
1824 while ((value
& -value
) != value
)
1825 value
-= value
& -value
;
1829 /* Decode an SVE shift-left immediate. */
1831 aarch64_ext_sve_shlimm (const aarch64_operand
*self
,
1832 aarch64_opnd_info
*info
, const aarch64_insn code
,
1833 const aarch64_inst
*inst
, aarch64_operand_error
*errors
)
1835 if (!aarch64_ext_imm (self
, info
, code
, inst
, errors
)
1836 || info
->imm
.value
== 0)
1839 info
->imm
.value
-= get_top_bit (info
->imm
.value
);
1843 /* Decode an SVE shift-right immediate. */
1845 aarch64_ext_sve_shrimm (const aarch64_operand
*self
,
1846 aarch64_opnd_info
*info
, const aarch64_insn code
,
1847 const aarch64_inst
*inst
, aarch64_operand_error
*errors
)
1849 if (!aarch64_ext_imm (self
, info
, code
, inst
, errors
)
1850 || info
->imm
.value
== 0)
1853 info
->imm
.value
= get_top_bit (info
->imm
.value
) * 2 - info
->imm
.value
;
1857 /* Bitfields that are commonly used to encode certain operands' information
1858 may be partially used as part of the base opcode in some instructions.
1859 For example, the bit 1 of the field 'size' in
1860 FCVTXN <Vb><d>, <Va><n>
1861 is actually part of the base opcode, while only size<0> is available
1862 for encoding the register type. Another example is the AdvSIMD
1863 instruction ORR (register), in which the field 'size' is also used for
1864 the base opcode, leaving only the field 'Q' available to encode the
1865 vector register arrangement specifier '8B' or '16B'.
1867 This function tries to deduce the qualifier from the value of partially
1868 constrained field(s). Given the VALUE of such a field or fields, the
1869 qualifiers CANDIDATES and the MASK (indicating which bits are valid for
1870 operand encoding), the function returns the matching qualifier or
1871 AARCH64_OPND_QLF_NIL if nothing matches.
1873 N.B. CANDIDATES is a group of possible qualifiers that are valid for
1874 one operand; it has a maximum of AARCH64_MAX_QLF_SEQ_NUM qualifiers and
1875 may end with AARCH64_OPND_QLF_NIL. */
1877 static enum aarch64_opnd_qualifier
1878 get_qualifier_from_partial_encoding (aarch64_insn value
,
1879 const enum aarch64_opnd_qualifier
* \
1884 DEBUG_TRACE ("enter with value: %d, mask: %d", (int)value
, (int)mask
);
1885 for (i
= 0; i
< AARCH64_MAX_QLF_SEQ_NUM
; ++i
)
1887 aarch64_insn standard_value
;
1888 if (candidates
[i
] == AARCH64_OPND_QLF_NIL
)
1890 standard_value
= aarch64_get_qualifier_standard_value (candidates
[i
]);
1891 if ((standard_value
& mask
) == (value
& mask
))
1892 return candidates
[i
];
1894 return AARCH64_OPND_QLF_NIL
;
1897 /* Given a list of qualifier sequences, return all possible valid qualifiers
1898 for operand IDX in QUALIFIERS.
1899 Assume QUALIFIERS is an array whose length is large enough. */
1902 get_operand_possible_qualifiers (int idx
,
1903 const aarch64_opnd_qualifier_seq_t
*list
,
1904 enum aarch64_opnd_qualifier
*qualifiers
)
1907 for (i
= 0; i
< AARCH64_MAX_QLF_SEQ_NUM
; ++i
)
1908 if ((qualifiers
[i
] = list
[i
][idx
]) == AARCH64_OPND_QLF_NIL
)
1912 /* Decode the size Q field for e.g. SHADD.
1913 We tag one operand with the qualifer according to the code;
1914 whether the qualifier is valid for this opcode or not, it is the
1915 duty of the semantic checking. */
1918 decode_sizeq (aarch64_inst
*inst
)
1921 enum aarch64_opnd_qualifier qualifier
;
1923 aarch64_insn value
, mask
;
1924 enum aarch64_field_kind fld_sz
;
1925 enum aarch64_opnd_qualifier candidates
[AARCH64_MAX_QLF_SEQ_NUM
];
1927 if (inst
->opcode
->iclass
== asisdlse
1928 || inst
->opcode
->iclass
== asisdlsep
1929 || inst
->opcode
->iclass
== asisdlso
1930 || inst
->opcode
->iclass
== asisdlsop
)
1931 fld_sz
= FLD_vldst_size
;
1936 value
= extract_fields (code
, inst
->opcode
->mask
, 2, fld_sz
, FLD_Q
);
1937 /* Obtain the info that which bits of fields Q and size are actually
1938 available for operand encoding. Opcodes like FMAXNM and FMLA have
1939 size[1] unavailable. */
1940 mask
= extract_fields (~inst
->opcode
->mask
, 0, 2, fld_sz
, FLD_Q
);
1942 /* The index of the operand we are going to tag a qualifier and the qualifer
1943 itself are reasoned from the value of the size and Q fields and the
1944 possible valid qualifier lists. */
1945 idx
= aarch64_select_operand_for_sizeq_field_coding (inst
->opcode
);
1946 DEBUG_TRACE ("key idx: %d", idx
);
1948 /* For most related instruciton, size:Q are fully available for operand
1952 inst
->operands
[idx
].qualifier
= get_vreg_qualifier_from_value (value
);
1956 get_operand_possible_qualifiers (idx
, inst
->opcode
->qualifiers_list
,
1958 #ifdef DEBUG_AARCH64
1962 for (i
= 0; candidates
[i
] != AARCH64_OPND_QLF_NIL
1963 && i
< AARCH64_MAX_QLF_SEQ_NUM
; ++i
)
1964 DEBUG_TRACE ("qualifier %d: %s", i
,
1965 aarch64_get_qualifier_name(candidates
[i
]));
1966 DEBUG_TRACE ("%d, %d", (int)value
, (int)mask
);
1968 #endif /* DEBUG_AARCH64 */
1970 qualifier
= get_qualifier_from_partial_encoding (value
, candidates
, mask
);
1972 if (qualifier
== AARCH64_OPND_QLF_NIL
)
1975 inst
->operands
[idx
].qualifier
= qualifier
;
1979 /* Decode size[0]:Q, i.e. bit 22 and bit 30, for
1980 e.g. FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>. */
1983 decode_asimd_fcvt (aarch64_inst
*inst
)
1985 aarch64_field field
= {0, 0};
1987 enum aarch64_opnd_qualifier qualifier
;
1989 gen_sub_field (FLD_size
, 0, 1, &field
);
1990 value
= extract_field_2 (&field
, inst
->value
, 0);
1991 qualifier
= value
== 0 ? AARCH64_OPND_QLF_V_4S
1992 : AARCH64_OPND_QLF_V_2D
;
1993 switch (inst
->opcode
->op
)
1997 /* FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>. */
1998 inst
->operands
[1].qualifier
= qualifier
;
2002 /* FCVTL<Q> <Vd>.<Ta>, <Vn>.<Tb>. */
2003 inst
->operands
[0].qualifier
= qualifier
;
2013 /* Decode size[0], i.e. bit 22, for
2014 e.g. FCVTXN <Vb><d>, <Va><n>. */
2017 decode_asisd_fcvtxn (aarch64_inst
*inst
)
2019 aarch64_field field
= {0, 0};
2020 gen_sub_field (FLD_size
, 0, 1, &field
);
2021 if (!extract_field_2 (&field
, inst
->value
, 0))
2023 inst
->operands
[0].qualifier
= AARCH64_OPND_QLF_S_S
;
2027 /* Decode the 'opc' field for e.g. FCVT <Dd>, <Sn>. */
2029 decode_fcvt (aarch64_inst
*inst
)
2031 enum aarch64_opnd_qualifier qualifier
;
2033 const aarch64_field field
= {15, 2};
2036 value
= extract_field_2 (&field
, inst
->value
, 0);
2039 case 0: qualifier
= AARCH64_OPND_QLF_S_S
; break;
2040 case 1: qualifier
= AARCH64_OPND_QLF_S_D
; break;
2041 case 3: qualifier
= AARCH64_OPND_QLF_S_H
; break;
2044 inst
->operands
[0].qualifier
= qualifier
;
2049 /* Do miscellaneous decodings that are not common enough to be driven by
2053 do_misc_decoding (aarch64_inst
*inst
)
2056 switch (inst
->opcode
->op
)
2059 return decode_fcvt (inst
);
2065 return decode_asimd_fcvt (inst
);
2068 return decode_asisd_fcvtxn (inst
);
2072 value
= extract_field (FLD_SVE_Pn
, inst
->value
, 0);
2073 return (value
== extract_field (FLD_SVE_Pm
, inst
->value
, 0)
2074 && value
== extract_field (FLD_SVE_Pg4_10
, inst
->value
, 0));
2077 return (extract_field (FLD_SVE_Zd
, inst
->value
, 0)
2078 == extract_field (FLD_SVE_Zm_16
, inst
->value
, 0));
2081 /* Index must be zero. */
2082 value
= extract_fields (inst
->value
, 0, 2, FLD_SVE_tszh
, FLD_imm5
);
2083 return value
> 0 && value
<= 16 && value
== (value
& -value
);
2086 return (extract_field (FLD_SVE_Zn
, inst
->value
, 0)
2087 == extract_field (FLD_SVE_Zm_16
, inst
->value
, 0));
2090 /* Index must be nonzero. */
2091 value
= extract_fields (inst
->value
, 0, 2, FLD_SVE_tszh
, FLD_imm5
);
2092 return value
> 0 && value
!= (value
& -value
);
2095 return (extract_field (FLD_SVE_Pd
, inst
->value
, 0)
2096 == extract_field (FLD_SVE_Pm
, inst
->value
, 0));
2098 case OP_MOVZS_P_P_P
:
2100 return (extract_field (FLD_SVE_Pn
, inst
->value
, 0)
2101 == extract_field (FLD_SVE_Pm
, inst
->value
, 0));
2103 case OP_NOTS_P_P_P_Z
:
2104 case OP_NOT_P_P_P_Z
:
2105 return (extract_field (FLD_SVE_Pm
, inst
->value
, 0)
2106 == extract_field (FLD_SVE_Pg4_10
, inst
->value
, 0));
2113 /* Opcodes that have fields shared by multiple operands are usually flagged
2114 with flags. In this function, we detect such flags, decode the related
2115 field(s) and store the information in one of the related operands. The
2116 'one' operand is not any operand but one of the operands that can
2117 accommadate all the information that has been decoded. */
2120 do_special_decoding (aarch64_inst
*inst
)
2124 /* Condition for truly conditional executed instructions, e.g. b.cond. */
2125 if (inst
->opcode
->flags
& F_COND
)
2127 value
= extract_field (FLD_cond2
, inst
->value
, 0);
2128 inst
->cond
= get_cond_from_value (value
);
2131 if (inst
->opcode
->flags
& F_SF
)
2133 idx
= select_operand_for_sf_field_coding (inst
->opcode
);
2134 value
= extract_field (FLD_sf
, inst
->value
, 0);
2135 inst
->operands
[idx
].qualifier
= get_greg_qualifier_from_value (value
);
2136 if ((inst
->opcode
->flags
& F_N
)
2137 && extract_field (FLD_N
, inst
->value
, 0) != value
)
2141 if (inst
->opcode
->flags
& F_LSE_SZ
)
2143 idx
= select_operand_for_sf_field_coding (inst
->opcode
);
2144 value
= extract_field (FLD_lse_sz
, inst
->value
, 0);
2145 inst
->operands
[idx
].qualifier
= get_greg_qualifier_from_value (value
);
2147 /* size:Q fields. */
2148 if (inst
->opcode
->flags
& F_SIZEQ
)
2149 return decode_sizeq (inst
);
2151 if (inst
->opcode
->flags
& F_FPTYPE
)
2153 idx
= select_operand_for_fptype_field_coding (inst
->opcode
);
2154 value
= extract_field (FLD_type
, inst
->value
, 0);
2157 case 0: inst
->operands
[idx
].qualifier
= AARCH64_OPND_QLF_S_S
; break;
2158 case 1: inst
->operands
[idx
].qualifier
= AARCH64_OPND_QLF_S_D
; break;
2159 case 3: inst
->operands
[idx
].qualifier
= AARCH64_OPND_QLF_S_H
; break;
2164 if (inst
->opcode
->flags
& F_SSIZE
)
2166 /* N.B. some opcodes like FCMGT <V><d>, <V><n>, #0 have the size[1] as part
2167 of the base opcode. */
2169 enum aarch64_opnd_qualifier candidates
[AARCH64_MAX_QLF_SEQ_NUM
];
2170 idx
= select_operand_for_scalar_size_field_coding (inst
->opcode
);
2171 value
= extract_field (FLD_size
, inst
->value
, inst
->opcode
->mask
);
2172 mask
= extract_field (FLD_size
, ~inst
->opcode
->mask
, 0);
2173 /* For most related instruciton, the 'size' field is fully available for
2174 operand encoding. */
2176 inst
->operands
[idx
].qualifier
= get_sreg_qualifier_from_value (value
);
2179 get_operand_possible_qualifiers (idx
, inst
->opcode
->qualifiers_list
,
2181 inst
->operands
[idx
].qualifier
2182 = get_qualifier_from_partial_encoding (value
, candidates
, mask
);
2186 if (inst
->opcode
->flags
& F_T
)
2188 /* Num of consecutive '0's on the right side of imm5<3:0>. */
2191 assert (aarch64_get_operand_class (inst
->opcode
->operands
[0])
2192 == AARCH64_OPND_CLASS_SIMD_REG
);
2203 val
= extract_field (FLD_imm5
, inst
->value
, 0);
2204 while ((val
& 0x1) == 0 && ++num
<= 3)
2208 Q
= (unsigned) extract_field (FLD_Q
, inst
->value
, inst
->opcode
->mask
);
2209 inst
->operands
[0].qualifier
=
2210 get_vreg_qualifier_from_value ((num
<< 1) | Q
);
2213 if (inst
->opcode
->flags
& F_GPRSIZE_IN_Q
)
2215 /* Use Rt to encode in the case of e.g.
2216 STXP <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}]. */
2217 idx
= aarch64_operand_index (inst
->opcode
->operands
, AARCH64_OPND_Rt
);
2220 /* Otherwise use the result operand, which has to be a integer
2222 assert (aarch64_get_operand_class (inst
->opcode
->operands
[0])
2223 == AARCH64_OPND_CLASS_INT_REG
);
2226 assert (idx
== 0 || idx
== 1);
2227 value
= extract_field (FLD_Q
, inst
->value
, 0);
2228 inst
->operands
[idx
].qualifier
= get_greg_qualifier_from_value (value
);
2231 if (inst
->opcode
->flags
& F_LDS_SIZE
)
2233 aarch64_field field
= {0, 0};
2234 assert (aarch64_get_operand_class (inst
->opcode
->operands
[0])
2235 == AARCH64_OPND_CLASS_INT_REG
);
2236 gen_sub_field (FLD_opc
, 0, 1, &field
);
2237 value
= extract_field_2 (&field
, inst
->value
, 0);
2238 inst
->operands
[0].qualifier
2239 = value
? AARCH64_OPND_QLF_W
: AARCH64_OPND_QLF_X
;
2242 /* Miscellaneous decoding; done as the last step. */
2243 if (inst
->opcode
->flags
& F_MISC
)
2244 return do_misc_decoding (inst
);
2249 /* Converters converting a real opcode instruction to its alias form. */
2251 /* ROR <Wd>, <Ws>, #<shift>
2253 EXTR <Wd>, <Ws>, <Ws>, #<shift>. */
2255 convert_extr_to_ror (aarch64_inst
*inst
)
2257 if (inst
->operands
[1].reg
.regno
== inst
->operands
[2].reg
.regno
)
2259 copy_operand_info (inst
, 2, 3);
2260 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
2266 /* UXTL<Q> <Vd>.<Ta>, <Vn>.<Tb>
2268 USHLL<Q> <Vd>.<Ta>, <Vn>.<Tb>, #0. */
2270 convert_shll_to_xtl (aarch64_inst
*inst
)
2272 if (inst
->operands
[2].imm
.value
== 0)
2274 inst
->operands
[2].type
= AARCH64_OPND_NIL
;
2281 UBFM <Xd>, <Xn>, #<shift>, #63.
2283 LSR <Xd>, <Xn>, #<shift>. */
2285 convert_bfm_to_sr (aarch64_inst
*inst
)
2289 imms
= inst
->operands
[3].imm
.value
;
2290 val
= inst
->operands
[2].qualifier
== AARCH64_OPND_QLF_imm_0_31
? 31 : 63;
2293 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
2300 /* Convert MOV to ORR. */
2302 convert_orr_to_mov (aarch64_inst
*inst
)
2304 /* MOV <Vd>.<T>, <Vn>.<T>
2306 ORR <Vd>.<T>, <Vn>.<T>, <Vn>.<T>. */
2307 if (inst
->operands
[1].reg
.regno
== inst
->operands
[2].reg
.regno
)
2309 inst
->operands
[2].type
= AARCH64_OPND_NIL
;
2315 /* When <imms> >= <immr>, the instruction written:
2316 SBFX <Xd>, <Xn>, #<lsb>, #<width>
2318 SBFM <Xd>, <Xn>, #<lsb>, #(<lsb>+<width>-1). */
2321 convert_bfm_to_bfx (aarch64_inst
*inst
)
2325 immr
= inst
->operands
[2].imm
.value
;
2326 imms
= inst
->operands
[3].imm
.value
;
2330 inst
->operands
[2].imm
.value
= lsb
;
2331 inst
->operands
[3].imm
.value
= imms
+ 1 - lsb
;
2332 /* The two opcodes have different qualifiers for
2333 the immediate operands; reset to help the checking. */
2334 reset_operand_qualifier (inst
, 2);
2335 reset_operand_qualifier (inst
, 3);
2342 /* When <imms> < <immr>, the instruction written:
2343 SBFIZ <Xd>, <Xn>, #<lsb>, #<width>
2345 SBFM <Xd>, <Xn>, #((64-<lsb>)&0x3f), #(<width>-1). */
2348 convert_bfm_to_bfi (aarch64_inst
*inst
)
2350 int64_t immr
, imms
, val
;
2352 immr
= inst
->operands
[2].imm
.value
;
2353 imms
= inst
->operands
[3].imm
.value
;
2354 val
= inst
->operands
[2].qualifier
== AARCH64_OPND_QLF_imm_0_31
? 32 : 64;
2357 inst
->operands
[2].imm
.value
= (val
- immr
) & (val
- 1);
2358 inst
->operands
[3].imm
.value
= imms
+ 1;
2359 /* The two opcodes have different qualifiers for
2360 the immediate operands; reset to help the checking. */
2361 reset_operand_qualifier (inst
, 2);
2362 reset_operand_qualifier (inst
, 3);
2369 /* The instruction written:
2370 BFC <Xd>, #<lsb>, #<width>
2372 BFM <Xd>, XZR, #((64-<lsb>)&0x3f), #(<width>-1). */
2375 convert_bfm_to_bfc (aarch64_inst
*inst
)
2377 int64_t immr
, imms
, val
;
2379 /* Should have been assured by the base opcode value. */
2380 assert (inst
->operands
[1].reg
.regno
== 0x1f);
2382 immr
= inst
->operands
[2].imm
.value
;
2383 imms
= inst
->operands
[3].imm
.value
;
2384 val
= inst
->operands
[2].qualifier
== AARCH64_OPND_QLF_imm_0_31
? 32 : 64;
2387 /* Drop XZR from the second operand. */
2388 copy_operand_info (inst
, 1, 2);
2389 copy_operand_info (inst
, 2, 3);
2390 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
2392 /* Recalculate the immediates. */
2393 inst
->operands
[1].imm
.value
= (val
- immr
) & (val
- 1);
2394 inst
->operands
[2].imm
.value
= imms
+ 1;
2396 /* The two opcodes have different qualifiers for the operands; reset to
2397 help the checking. */
2398 reset_operand_qualifier (inst
, 1);
2399 reset_operand_qualifier (inst
, 2);
2400 reset_operand_qualifier (inst
, 3);
2408 /* The instruction written:
2409 LSL <Xd>, <Xn>, #<shift>
2411 UBFM <Xd>, <Xn>, #((64-<shift>)&0x3f), #(63-<shift>). */
2414 convert_ubfm_to_lsl (aarch64_inst
*inst
)
2416 int64_t immr
= inst
->operands
[2].imm
.value
;
2417 int64_t imms
= inst
->operands
[3].imm
.value
;
2419 = inst
->operands
[2].qualifier
== AARCH64_OPND_QLF_imm_0_31
? 31 : 63;
2421 if ((immr
== 0 && imms
== val
) || immr
== imms
+ 1)
2423 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
2424 inst
->operands
[2].imm
.value
= val
- imms
;
2431 /* CINC <Wd>, <Wn>, <cond>
2433 CSINC <Wd>, <Wn>, <Wn>, invert(<cond>)
2434 where <cond> is not AL or NV. */
2437 convert_from_csel (aarch64_inst
*inst
)
2439 if (inst
->operands
[1].reg
.regno
== inst
->operands
[2].reg
.regno
2440 && (inst
->operands
[3].cond
->value
& 0xe) != 0xe)
2442 copy_operand_info (inst
, 2, 3);
2443 inst
->operands
[2].cond
= get_inverted_cond (inst
->operands
[3].cond
);
2444 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
2450 /* CSET <Wd>, <cond>
2452 CSINC <Wd>, WZR, WZR, invert(<cond>)
2453 where <cond> is not AL or NV. */
2456 convert_csinc_to_cset (aarch64_inst
*inst
)
2458 if (inst
->operands
[1].reg
.regno
== 0x1f
2459 && inst
->operands
[2].reg
.regno
== 0x1f
2460 && (inst
->operands
[3].cond
->value
& 0xe) != 0xe)
2462 copy_operand_info (inst
, 1, 3);
2463 inst
->operands
[1].cond
= get_inverted_cond (inst
->operands
[3].cond
);
2464 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
2465 inst
->operands
[2].type
= AARCH64_OPND_NIL
;
2473 MOVZ <Wd>, #<imm16>, LSL #<shift>.
2475 A disassembler may output ORR, MOVZ and MOVN as a MOV mnemonic, except when
2476 ORR has an immediate that could be generated by a MOVZ or MOVN instruction,
2477 or where a MOVN has an immediate that could be encoded by MOVZ, or where
2478 MOVZ/MOVN #0 have a shift amount other than LSL #0, in which case the
2479 machine-instruction mnemonic must be used. */
2482 convert_movewide_to_mov (aarch64_inst
*inst
)
2484 uint64_t value
= inst
->operands
[1].imm
.value
;
2485 /* MOVZ/MOVN #0 have a shift amount other than LSL #0. */
2486 if (value
== 0 && inst
->operands
[1].shifter
.amount
!= 0)
2488 inst
->operands
[1].type
= AARCH64_OPND_IMM_MOV
;
2489 inst
->operands
[1].shifter
.kind
= AARCH64_MOD_NONE
;
2490 value
<<= inst
->operands
[1].shifter
.amount
;
2491 /* As an alias convertor, it has to be clear that the INST->OPCODE
2492 is the opcode of the real instruction. */
2493 if (inst
->opcode
->op
== OP_MOVN
)
2495 int is32
= inst
->operands
[0].qualifier
== AARCH64_OPND_QLF_W
;
2497 /* A MOVN has an immediate that could be encoded by MOVZ. */
2498 if (aarch64_wide_constant_p (value
, is32
, NULL
))
2501 inst
->operands
[1].imm
.value
= value
;
2502 inst
->operands
[1].shifter
.amount
= 0;
2508 ORR <Wd>, WZR, #<imm>.
2510 A disassembler may output ORR, MOVZ and MOVN as a MOV mnemonic, except when
2511 ORR has an immediate that could be generated by a MOVZ or MOVN instruction,
2512 or where a MOVN has an immediate that could be encoded by MOVZ, or where
2513 MOVZ/MOVN #0 have a shift amount other than LSL #0, in which case the
2514 machine-instruction mnemonic must be used. */
2517 convert_movebitmask_to_mov (aarch64_inst
*inst
)
2522 /* Should have been assured by the base opcode value. */
2523 assert (inst
->operands
[1].reg
.regno
== 0x1f);
2524 copy_operand_info (inst
, 1, 2);
2525 is32
= inst
->operands
[0].qualifier
== AARCH64_OPND_QLF_W
;
2526 inst
->operands
[1].type
= AARCH64_OPND_IMM_MOV
;
2527 value
= inst
->operands
[1].imm
.value
;
2528 /* ORR has an immediate that could be generated by a MOVZ or MOVN
2530 if (inst
->operands
[0].reg
.regno
!= 0x1f
2531 && (aarch64_wide_constant_p (value
, is32
, NULL
)
2532 || aarch64_wide_constant_p (~value
, is32
, NULL
)))
2535 inst
->operands
[2].type
= AARCH64_OPND_NIL
;
2539 /* Some alias opcodes are disassembled by being converted from their real-form.
2540 N.B. INST->OPCODE is the real opcode rather than the alias. */
2543 convert_to_alias (aarch64_inst
*inst
, const aarch64_opcode
*alias
)
2549 return convert_bfm_to_sr (inst
);
2551 return convert_ubfm_to_lsl (inst
);
2555 return convert_from_csel (inst
);
2558 return convert_csinc_to_cset (inst
);
2562 return convert_bfm_to_bfx (inst
);
2566 return convert_bfm_to_bfi (inst
);
2568 return convert_bfm_to_bfc (inst
);
2570 return convert_orr_to_mov (inst
);
2571 case OP_MOV_IMM_WIDE
:
2572 case OP_MOV_IMM_WIDEN
:
2573 return convert_movewide_to_mov (inst
);
2574 case OP_MOV_IMM_LOG
:
2575 return convert_movebitmask_to_mov (inst
);
2577 return convert_extr_to_ror (inst
);
2582 return convert_shll_to_xtl (inst
);
2589 aarch64_opcode_decode (const aarch64_opcode
*, const aarch64_insn
,
2590 aarch64_inst
*, int, aarch64_operand_error
*errors
);
2592 /* Given the instruction information in *INST, check if the instruction has
2593 any alias form that can be used to represent *INST. If the answer is yes,
2594 update *INST to be in the form of the determined alias. */
2596 /* In the opcode description table, the following flags are used in opcode
2597 entries to help establish the relations between the real and alias opcodes:
2599 F_ALIAS: opcode is an alias
2600 F_HAS_ALIAS: opcode has alias(es)
2603 F_P3: Disassembly preference priority 1-3 (the larger the
2604 higher). If nothing is specified, it is the priority
2605 0 by default, i.e. the lowest priority.
2607 Although the relation between the machine and the alias instructions are not
2608 explicitly described, it can be easily determined from the base opcode
2609 values, masks and the flags F_ALIAS and F_HAS_ALIAS in their opcode
2610 description entries:
2612 The mask of an alias opcode must be equal to or a super-set (i.e. more
2613 constrained) of that of the aliased opcode; so is the base opcode value.
2615 if (opcode_has_alias (real) && alias_opcode_p (opcode)
2616 && (opcode->mask & real->mask) == real->mask
2617 && (real->mask & opcode->opcode) == (real->mask & real->opcode))
2618 then OPCODE is an alias of, and only of, the REAL instruction
2620 The alias relationship is forced flat-structured to keep related algorithm
2621 simple; an opcode entry cannot be flagged with both F_ALIAS and F_HAS_ALIAS.
2623 During the disassembling, the decoding decision tree (in
2624 opcodes/aarch64-dis-2.c) always returns an machine instruction opcode entry;
2625 if the decoding of such a machine instruction succeeds (and -Mno-aliases is
2626 not specified), the disassembler will check whether there is any alias
2627 instruction exists for this real instruction. If there is, the disassembler
2628 will try to disassemble the 32-bit binary again using the alias's rule, or
2629 try to convert the IR to the form of the alias. In the case of the multiple
2630 aliases, the aliases are tried one by one from the highest priority
2631 (currently the flag F_P3) to the lowest priority (no priority flag), and the
2632 first succeeds first adopted.
2634 You may ask why there is a need for the conversion of IR from one form to
2635 another in handling certain aliases. This is because on one hand it avoids
2636 adding more operand code to handle unusual encoding/decoding; on other
2637 hand, during the disassembling, the conversion is an effective approach to
2638 check the condition of an alias (as an alias may be adopted only if certain
2639 conditions are met).
2641 In order to speed up the alias opcode lookup, aarch64-gen has preprocessed
2642 aarch64_opcode_table and generated aarch64_find_alias_opcode and
2643 aarch64_find_next_alias_opcode (in opcodes/aarch64-dis-2.c) to help. */
2646 determine_disassembling_preference (struct aarch64_inst
*inst
,
2647 aarch64_operand_error
*errors
)
2649 const aarch64_opcode
*opcode
;
2650 const aarch64_opcode
*alias
;
2652 opcode
= inst
->opcode
;
2654 /* This opcode does not have an alias, so use itself. */
2655 if (!opcode_has_alias (opcode
))
2658 alias
= aarch64_find_alias_opcode (opcode
);
2661 #ifdef DEBUG_AARCH64
2664 const aarch64_opcode
*tmp
= alias
;
2665 printf ("#### LIST orderd: ");
2668 printf ("%s, ", tmp
->name
);
2669 tmp
= aarch64_find_next_alias_opcode (tmp
);
2673 #endif /* DEBUG_AARCH64 */
2675 for (; alias
; alias
= aarch64_find_next_alias_opcode (alias
))
2677 DEBUG_TRACE ("try %s", alias
->name
);
2678 assert (alias_opcode_p (alias
) || opcode_has_alias (opcode
));
2680 /* An alias can be a pseudo opcode which will never be used in the
2681 disassembly, e.g. BIC logical immediate is such a pseudo opcode
2683 if (pseudo_opcode_p (alias
))
2685 DEBUG_TRACE ("skip pseudo %s", alias
->name
);
2689 if ((inst
->value
& alias
->mask
) != alias
->opcode
)
2691 DEBUG_TRACE ("skip %s as base opcode not match", alias
->name
);
2695 if (!AARCH64_CPU_HAS_FEATURE (arch_variant
, *alias
->avariant
))
2697 DEBUG_TRACE ("skip %s: we're missing features", alias
->name
);
2701 /* No need to do any complicated transformation on operands, if the alias
2702 opcode does not have any operand. */
2703 if (aarch64_num_of_operands (alias
) == 0 && alias
->opcode
== inst
->value
)
2705 DEBUG_TRACE ("succeed with 0-operand opcode %s", alias
->name
);
2706 aarch64_replace_opcode (inst
, alias
);
2709 if (alias
->flags
& F_CONV
)
2712 memcpy (©
, inst
, sizeof (aarch64_inst
));
2713 /* ALIAS is the preference as long as the instruction can be
2714 successfully converted to the form of ALIAS. */
2715 if (convert_to_alias (©
, alias
) == 1)
2717 aarch64_replace_opcode (©
, alias
);
2718 assert (aarch64_match_operands_constraint (©
, NULL
));
2719 DEBUG_TRACE ("succeed with %s via conversion", alias
->name
);
2720 memcpy (inst
, ©
, sizeof (aarch64_inst
));
2726 /* Directly decode the alias opcode. */
2728 memset (&temp
, '\0', sizeof (aarch64_inst
));
2729 if (aarch64_opcode_decode (alias
, inst
->value
, &temp
, 1, errors
) == 1)
2731 DEBUG_TRACE ("succeed with %s via direct decoding", alias
->name
);
2732 memcpy (inst
, &temp
, sizeof (aarch64_inst
));
2739 /* Some instructions (including all SVE ones) use the instruction class
2740 to describe how a qualifiers_list index is represented in the instruction
2741 encoding. If INST is such an instruction, decode the appropriate fields
2742 and fill in the operand qualifiers accordingly. Return true if no
2743 problems are found. */
2746 aarch64_decode_variant_using_iclass (aarch64_inst
*inst
)
2751 switch (inst
->opcode
->iclass
)
2754 variant
= extract_fields (inst
->value
, 0, 2, FLD_size
, FLD_SVE_M_14
);
2758 i
= extract_fields (inst
->value
, 0, 2, FLD_SVE_tszh
, FLD_imm5
);
2761 while ((i
& 1) == 0)
2769 /* Pick the smallest applicable element size. */
2770 if ((inst
->value
& 0x20600) == 0x600)
2772 else if ((inst
->value
& 0x20400) == 0x400)
2774 else if ((inst
->value
& 0x20000) == 0)
2781 /* sve_misc instructions have only a single variant. */
2785 variant
= extract_fields (inst
->value
, 0, 2, FLD_size
, FLD_SVE_M_16
);
2789 variant
= extract_field (FLD_SVE_M_4
, inst
->value
, 0);
2792 case sve_shift_pred
:
2793 i
= extract_fields (inst
->value
, 0, 2, FLD_SVE_tszh
, FLD_SVE_tszl_8
);
2804 case sve_shift_unpred
:
2805 i
= extract_fields (inst
->value
, 0, 2, FLD_SVE_tszh
, FLD_SVE_tszl_19
);
2809 variant
= extract_field (FLD_size
, inst
->value
, 0);
2815 variant
= extract_field (FLD_size
, inst
->value
, 0);
2819 i
= extract_field (FLD_size
, inst
->value
, 0);
2827 variant
= extract_field (FLD_SVE_sz
, inst
->value
, 0);
2831 variant
= extract_field (FLD_SVE_sz2
, inst
->value
, 0);
2835 i
= extract_field (FLD_SVE_size
, inst
->value
, 0);
2842 /* Ignore low bit of this field since that is set in the opcode for
2843 instructions of this iclass. */
2844 i
= (extract_field (FLD_size
, inst
->value
, 0) & 2);
2848 case sve_shift_tsz_bhsd
:
2849 i
= extract_fields (inst
->value
, 0, 2, FLD_SVE_tszh
, FLD_SVE_tszl_19
);
2859 case sve_size_tsz_bhs
:
2860 i
= extract_fields (inst
->value
, 0, 2, FLD_SVE_sz
, FLD_SVE_tszl_19
);
2872 case sve_shift_tsz_hsd
:
2873 i
= extract_fields (inst
->value
, 0, 2, FLD_SVE_sz
, FLD_SVE_tszl_19
);
2884 /* No mapping between instruction class and qualifiers. */
2888 for (i
= 0; i
< AARCH64_MAX_OPND_NUM
; ++i
)
2889 inst
->operands
[i
].qualifier
= inst
->opcode
->qualifiers_list
[variant
][i
];
2892 /* Decode the CODE according to OPCODE; fill INST. Return 0 if the decoding
2893 fails, which meanes that CODE is not an instruction of OPCODE; otherwise
2896 If OPCODE has alias(es) and NOALIASES_P is 0, an alias opcode may be
2897 determined and used to disassemble CODE; this is done just before the
2901 aarch64_opcode_decode (const aarch64_opcode
*opcode
, const aarch64_insn code
,
2902 aarch64_inst
*inst
, int noaliases_p
,
2903 aarch64_operand_error
*errors
)
2907 DEBUG_TRACE ("enter with %s", opcode
->name
);
2909 assert (opcode
&& inst
);
2912 memset (inst
, '\0', sizeof (aarch64_inst
));
2914 /* Check the base opcode. */
2915 if ((code
& opcode
->mask
) != (opcode
->opcode
& opcode
->mask
))
2917 DEBUG_TRACE ("base opcode match FAIL");
2921 inst
->opcode
= opcode
;
2924 /* Assign operand codes and indexes. */
2925 for (i
= 0; i
< AARCH64_MAX_OPND_NUM
; ++i
)
2927 if (opcode
->operands
[i
] == AARCH64_OPND_NIL
)
2929 inst
->operands
[i
].type
= opcode
->operands
[i
];
2930 inst
->operands
[i
].idx
= i
;
2933 /* Call the opcode decoder indicated by flags. */
2934 if (opcode_has_special_coder (opcode
) && do_special_decoding (inst
) == 0)
2936 DEBUG_TRACE ("opcode flag-based decoder FAIL");
2940 /* Possibly use the instruction class to determine the correct
2942 if (!aarch64_decode_variant_using_iclass (inst
))
2944 DEBUG_TRACE ("iclass-based decoder FAIL");
2948 /* Call operand decoders. */
2949 for (i
= 0; i
< AARCH64_MAX_OPND_NUM
; ++i
)
2951 const aarch64_operand
*opnd
;
2952 enum aarch64_opnd type
;
2954 type
= opcode
->operands
[i
];
2955 if (type
== AARCH64_OPND_NIL
)
2957 opnd
= &aarch64_operands
[type
];
2958 if (operand_has_extractor (opnd
)
2959 && (! aarch64_extract_operand (opnd
, &inst
->operands
[i
], code
, inst
,
2962 DEBUG_TRACE ("operand decoder FAIL at operand %d", i
);
2967 /* If the opcode has a verifier, then check it now. */
2968 if (opcode
->verifier
2969 && opcode
->verifier (inst
, code
, 0, FALSE
, errors
, NULL
) != ERR_OK
)
2971 DEBUG_TRACE ("operand verifier FAIL");
2975 /* Match the qualifiers. */
2976 if (aarch64_match_operands_constraint (inst
, NULL
) == 1)
2978 /* Arriving here, the CODE has been determined as a valid instruction
2979 of OPCODE and *INST has been filled with information of this OPCODE
2980 instruction. Before the return, check if the instruction has any
2981 alias and should be disassembled in the form of its alias instead.
2982 If the answer is yes, *INST will be updated. */
2984 determine_disassembling_preference (inst
, errors
);
2985 DEBUG_TRACE ("SUCCESS");
2990 DEBUG_TRACE ("constraint matching FAIL");
2997 /* This does some user-friendly fix-up to *INST. It is currently focus on
2998 the adjustment of qualifiers to help the printed instruction
2999 recognized/understood more easily. */
3002 user_friendly_fixup (aarch64_inst
*inst
)
3004 switch (inst
->opcode
->iclass
)
3007 /* TBNZ Xn|Wn, #uimm6, label
3008 Test and Branch Not Zero: conditionally jumps to label if bit number
3009 uimm6 in register Xn is not zero. The bit number implies the width of
3010 the register, which may be written and should be disassembled as Wn if
3011 uimm is less than 32. Limited to a branch offset range of +/- 32KiB.
3013 if (inst
->operands
[1].imm
.value
< 32)
3014 inst
->operands
[0].qualifier
= AARCH64_OPND_QLF_W
;
3020 /* Decode INSN and fill in *INST the instruction information. An alias
3021 opcode may be filled in *INSN if NOALIASES_P is FALSE. Return zero on
3025 aarch64_decode_insn (aarch64_insn insn
, aarch64_inst
*inst
,
3026 bfd_boolean noaliases_p
,
3027 aarch64_operand_error
*errors
)
3029 const aarch64_opcode
*opcode
= aarch64_opcode_lookup (insn
);
3031 #ifdef DEBUG_AARCH64
3034 const aarch64_opcode
*tmp
= opcode
;
3036 DEBUG_TRACE ("opcode lookup:");
3039 aarch64_verbose (" %s", tmp
->name
);
3040 tmp
= aarch64_find_next_opcode (tmp
);
3043 #endif /* DEBUG_AARCH64 */
3045 /* A list of opcodes may have been found, as aarch64_opcode_lookup cannot
3046 distinguish some opcodes, e.g. SSHR and MOVI, which almost share the same
3047 opcode field and value, apart from the difference that one of them has an
3048 extra field as part of the opcode, but such a field is used for operand
3049 encoding in other opcode(s) ('immh' in the case of the example). */
3050 while (opcode
!= NULL
)
3052 /* But only one opcode can be decoded successfully for, as the
3053 decoding routine will check the constraint carefully. */
3054 if (aarch64_opcode_decode (opcode
, insn
, inst
, noaliases_p
, errors
) == 1)
3056 opcode
= aarch64_find_next_opcode (opcode
);
3062 /* Print operands. */
3065 print_operands (bfd_vma pc
, const aarch64_opcode
*opcode
,
3066 const aarch64_opnd_info
*opnds
, struct disassemble_info
*info
,
3067 bfd_boolean
*has_notes
)
3070 int i
, pcrel_p
, num_printed
;
3071 for (i
= 0, num_printed
= 0; i
< AARCH64_MAX_OPND_NUM
; ++i
)
3074 /* We regard the opcode operand info more, however we also look into
3075 the inst->operands to support the disassembling of the optional
3077 The two operand code should be the same in all cases, apart from
3078 when the operand can be optional. */
3079 if (opcode
->operands
[i
] == AARCH64_OPND_NIL
3080 || opnds
[i
].type
== AARCH64_OPND_NIL
)
3083 /* Generate the operand string in STR. */
3084 aarch64_print_operand (str
, sizeof (str
), pc
, opcode
, opnds
, i
, &pcrel_p
,
3085 &info
->target
, ¬es
);
3087 /* Print the delimiter (taking account of omitted operand(s)). */
3089 (*info
->fprintf_func
) (info
->stream
, "%s",
3090 num_printed
++ == 0 ? "\t" : ", ");
3092 /* Print the operand. */
3094 (*info
->print_address_func
) (info
->target
, info
);
3096 (*info
->fprintf_func
) (info
->stream
, "%s", str
);
3099 if (notes
&& !no_notes
)
3102 (*info
->fprintf_func
) (info
->stream
, " // note: %s", notes
);
3106 /* Set NAME to a copy of INST's mnemonic with the "." suffix removed. */
3109 remove_dot_suffix (char *name
, const aarch64_inst
*inst
)
3114 ptr
= strchr (inst
->opcode
->name
, '.');
3115 assert (ptr
&& inst
->cond
);
3116 len
= ptr
- inst
->opcode
->name
;
3118 strncpy (name
, inst
->opcode
->name
, len
);
3122 /* Print the instruction mnemonic name. */
3125 print_mnemonic_name (const aarch64_inst
*inst
, struct disassemble_info
*info
)
3127 if (inst
->opcode
->flags
& F_COND
)
3129 /* For instructions that are truly conditionally executed, e.g. b.cond,
3130 prepare the full mnemonic name with the corresponding condition
3134 remove_dot_suffix (name
, inst
);
3135 (*info
->fprintf_func
) (info
->stream
, "%s.%s", name
, inst
->cond
->names
[0]);
3138 (*info
->fprintf_func
) (info
->stream
, "%s", inst
->opcode
->name
);
3141 /* Decide whether we need to print a comment after the operands of
3142 instruction INST. */
3145 print_comment (const aarch64_inst
*inst
, struct disassemble_info
*info
)
3147 if (inst
->opcode
->flags
& F_COND
)
3150 unsigned int i
, num_conds
;
3152 remove_dot_suffix (name
, inst
);
3153 num_conds
= ARRAY_SIZE (inst
->cond
->names
);
3154 for (i
= 1; i
< num_conds
&& inst
->cond
->names
[i
]; ++i
)
3155 (*info
->fprintf_func
) (info
->stream
, "%s %s.%s",
3156 i
== 1 ? " //" : ",",
3157 name
, inst
->cond
->names
[i
]);
3161 /* Build notes from verifiers into a string for printing. */
3164 print_verifier_notes (aarch64_operand_error
*detail
,
3165 struct disassemble_info
*info
)
3170 /* The output of the verifier cannot be a fatal error, otherwise the assembly
3171 would not have succeeded. We can safely ignore these. */
3172 assert (detail
->non_fatal
);
3173 assert (detail
->error
);
3175 /* If there are multiple verifier messages, concat them up to 1k. */
3176 (*info
->fprintf_func
) (info
->stream
, " // note: %s", detail
->error
);
3177 if (detail
->index
>= 0)
3178 (*info
->fprintf_func
) (info
->stream
, " at operand %d", detail
->index
+ 1);
3181 /* Print the instruction according to *INST. */
3184 print_aarch64_insn (bfd_vma pc
, const aarch64_inst
*inst
,
3185 const aarch64_insn code
,
3186 struct disassemble_info
*info
,
3187 aarch64_operand_error
*mismatch_details
)
3189 bfd_boolean has_notes
= FALSE
;
3191 print_mnemonic_name (inst
, info
);
3192 print_operands (pc
, inst
->opcode
, inst
->operands
, info
, &has_notes
);
3193 print_comment (inst
, info
);
3195 /* We've already printed a note, not enough space to print more so exit.
3196 Usually notes shouldn't overlap so it shouldn't happen that we have a note
3197 from a register and instruction at the same time. */
3201 /* Always run constraint verifiers, this is needed because constraints need to
3202 maintain a global state regardless of whether the instruction has the flag
3204 enum err_type result
= verify_constraints (inst
, code
, pc
, FALSE
,
3205 mismatch_details
, &insn_sequence
);
3213 print_verifier_notes (mismatch_details
, info
);
3220 /* Entry-point of the instruction disassembler and printer. */
3223 print_insn_aarch64_word (bfd_vma pc
,
3225 struct disassemble_info
*info
,
3226 aarch64_operand_error
*errors
)
3228 static const char *err_msg
[ERR_NR_ENTRIES
+1] =
3231 [ERR_UND
] = "undefined",
3232 [ERR_UNP
] = "unpredictable",
3239 info
->insn_info_valid
= 1;
3240 info
->branch_delay_insns
= 0;
3241 info
->data_size
= 0;
3245 if (info
->flags
& INSN_HAS_RELOC
)
3246 /* If the instruction has a reloc associated with it, then
3247 the offset field in the instruction will actually be the
3248 addend for the reloc. (If we are using REL type relocs).
3249 In such cases, we can ignore the pc when computing
3250 addresses, since the addend is not currently pc-relative. */
3253 ret
= aarch64_decode_insn (word
, &inst
, no_aliases
, errors
);
3255 if (((word
>> 21) & 0x3ff) == 1)
3257 /* RESERVED for ALES. */
3258 assert (ret
!= ERR_OK
);
3267 /* Handle undefined instructions. */
3268 info
->insn_type
= dis_noninsn
;
3269 (*info
->fprintf_func
) (info
->stream
,".inst\t0x%08x ; %s",
3270 word
, err_msg
[ret
]);
3273 user_friendly_fixup (&inst
);
3274 print_aarch64_insn (pc
, &inst
, word
, info
, errors
);
3281 /* Disallow mapping symbols ($x, $d etc) from
3282 being displayed in symbol relative addresses. */
3285 aarch64_symbol_is_valid (asymbol
* sym
,
3286 struct disassemble_info
* info ATTRIBUTE_UNUSED
)
3293 name
= bfd_asymbol_name (sym
);
3297 || (name
[1] != 'x' && name
[1] != 'd')
3298 || (name
[2] != '\0' && name
[2] != '.'));
3301 /* Print data bytes on INFO->STREAM. */
3304 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED
,
3306 struct disassemble_info
*info
,
3307 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
3309 switch (info
->bytes_per_chunk
)
3312 info
->fprintf_func (info
->stream
, ".byte\t0x%02x", word
);
3315 info
->fprintf_func (info
->stream
, ".short\t0x%04x", word
);
3318 info
->fprintf_func (info
->stream
, ".word\t0x%08x", word
);
3325 /* Try to infer the code or data type from a symbol.
3326 Returns nonzero if *MAP_TYPE was set. */
3329 get_sym_code_type (struct disassemble_info
*info
, int n
,
3330 enum map_type
*map_type
)
3333 elf_symbol_type
*es
;
3337 /* If the symbol is in a different section, ignore it. */
3338 if (info
->section
!= NULL
&& info
->section
!= info
->symtab
[n
]->section
)
3341 if (n
>= info
->symtab_size
)
3344 as
= info
->symtab
[n
];
3345 if (bfd_asymbol_flavour (as
) != bfd_target_elf_flavour
)
3347 es
= (elf_symbol_type
*) as
;
3349 type
= ELF_ST_TYPE (es
->internal_elf_sym
.st_info
);
3351 /* If the symbol has function type then use that. */
3352 if (type
== STT_FUNC
)
3354 *map_type
= MAP_INSN
;
3358 /* Check for mapping symbols. */
3359 name
= bfd_asymbol_name(info
->symtab
[n
]);
3361 && (name
[1] == 'x' || name
[1] == 'd')
3362 && (name
[2] == '\0' || name
[2] == '.'))
3364 *map_type
= (name
[1] == 'x' ? MAP_INSN
: MAP_DATA
);
3371 /* Set the feature bits in arch_variant in order to get the correct disassembly
3372 for the chosen architecture variant.
3374 Currently we only restrict disassembly for Armv8-R and otherwise enable all
3375 non-R-profile features. */
3377 select_aarch64_variant (unsigned mach
)
3381 case bfd_mach_aarch64_8R
:
3382 arch_variant
= AARCH64_ARCH_V8_R
;
3385 arch_variant
= AARCH64_ANY
& ~(AARCH64_FEATURE_V8_R
);
3389 /* Entry-point of the AArch64 disassembler. */
3392 print_insn_aarch64 (bfd_vma pc
,
3393 struct disassemble_info
*info
)
3395 bfd_byte buffer
[INSNLEN
];
3397 void (*printer
) (bfd_vma
, uint32_t, struct disassemble_info
*,
3398 aarch64_operand_error
*);
3399 bfd_boolean found
= FALSE
;
3400 unsigned int size
= 4;
3402 aarch64_operand_error errors
;
3403 static bfd_boolean set_features
;
3405 if (info
->disassembler_options
)
3407 set_default_aarch64_dis_options (info
);
3409 parse_aarch64_dis_options (info
->disassembler_options
);
3411 /* To avoid repeated parsing of these options, we remove them here. */
3412 info
->disassembler_options
= NULL
;
3417 select_aarch64_variant (info
->mach
);
3418 set_features
= TRUE
;
3421 /* Aarch64 instructions are always little-endian */
3422 info
->endian_code
= BFD_ENDIAN_LITTLE
;
3424 /* Default to DATA. A text section is required by the ABI to contain an
3425 INSN mapping symbol at the start. A data section has no such
3426 requirement, hence if no mapping symbol is found the section must
3427 contain only data. This however isn't very useful if the user has
3428 fully stripped the binaries. If this is the case use the section
3429 attributes to determine the default. If we have no section default to
3430 INSN as well, as we may be disassembling some raw bytes on a baremetal
3431 HEX file or similar. */
3432 enum map_type type
= MAP_DATA
;
3433 if ((info
->section
&& info
->section
->flags
& SEC_CODE
) || !info
->section
)
3436 /* First check the full symtab for a mapping symbol, even if there
3437 are no usable non-mapping symbols for this address. */
3438 if (info
->symtab_size
!= 0
3439 && bfd_asymbol_flavour (*info
->symtab
) == bfd_target_elf_flavour
)
3442 bfd_vma addr
, section_vma
= 0;
3443 bfd_boolean can_use_search_opt_p
;
3446 if (pc
<= last_mapping_addr
)
3447 last_mapping_sym
= -1;
3449 /* Start scanning at the start of the function, or wherever
3450 we finished last time. */
3451 n
= info
->symtab_pos
+ 1;
3453 /* If the last stop offset is different from the current one it means we
3454 are disassembling a different glob of bytes. As such the optimization
3455 would not be safe and we should start over. */
3456 can_use_search_opt_p
= last_mapping_sym
>= 0
3457 && info
->stop_offset
== last_stop_offset
;
3459 if (n
>= last_mapping_sym
&& can_use_search_opt_p
)
3460 n
= last_mapping_sym
;
3462 /* Look down while we haven't passed the location being disassembled.
3463 The reason for this is that there's no defined order between a symbol
3464 and an mapping symbol that may be at the same address. We may have to
3465 look at least one position ahead. */
3466 for (; n
< info
->symtab_size
; n
++)
3468 addr
= bfd_asymbol_value (info
->symtab
[n
]);
3471 if (get_sym_code_type (info
, n
, &type
))
3480 n
= info
->symtab_pos
;
3481 if (n
>= last_mapping_sym
&& can_use_search_opt_p
)
3482 n
= last_mapping_sym
;
3484 /* No mapping symbol found at this address. Look backwards
3485 for a preceeding one, but don't go pass the section start
3486 otherwise a data section with no mapping symbol can pick up
3487 a text mapping symbol of a preceeding section. The documentation
3488 says section can be NULL, in which case we will seek up all the
3491 section_vma
= info
->section
->vma
;
3495 addr
= bfd_asymbol_value (info
->symtab
[n
]);
3496 if (addr
< section_vma
)
3499 if (get_sym_code_type (info
, n
, &type
))
3508 last_mapping_sym
= last_sym
;
3510 last_stop_offset
= info
->stop_offset
;
3512 /* Look a little bit ahead to see if we should print out
3513 less than four bytes of data. If there's a symbol,
3514 mapping or otherwise, after two bytes then don't
3516 if (last_type
== MAP_DATA
)
3518 size
= 4 - (pc
& 3);
3519 for (n
= last_sym
+ 1; n
< info
->symtab_size
; n
++)
3521 addr
= bfd_asymbol_value (info
->symtab
[n
]);
3524 if (addr
- pc
< size
)
3529 /* If the next symbol is after three bytes, we need to
3530 print only part of the data, so that we can use either
3533 size
= (pc
& 1) ? 1 : 2;
3539 /* PR 10263: Disassemble data if requested to do so by the user. */
3540 if (last_type
== MAP_DATA
&& ((info
->flags
& DISASSEMBLE_DATA
) == 0))
3542 /* size was set above. */
3543 info
->bytes_per_chunk
= size
;
3544 info
->display_endian
= info
->endian
;
3545 printer
= print_insn_data
;
3549 info
->bytes_per_chunk
= size
= INSNLEN
;
3550 info
->display_endian
= info
->endian_code
;
3551 printer
= print_insn_aarch64_word
;
3554 status
= (*info
->read_memory_func
) (pc
, buffer
, size
, info
);
3557 (*info
->memory_error_func
) (status
, pc
, info
);
3561 data
= bfd_get_bits (buffer
, size
* 8,
3562 info
->display_endian
== BFD_ENDIAN_BIG
);
3564 (*printer
) (pc
, data
, info
, &errors
);
3570 print_aarch64_disassembler_options (FILE *stream
)
3572 fprintf (stream
, _("\n\
3573 The following AARCH64 specific disassembler options are supported for use\n\
3574 with the -M switch (multiple options should be separated by commas):\n"));
3576 fprintf (stream
, _("\n\
3577 no-aliases Don't print instruction aliases.\n"));
3579 fprintf (stream
, _("\n\
3580 aliases Do print instruction aliases.\n"));
3582 fprintf (stream
, _("\n\
3583 no-notes Don't print instruction notes.\n"));
3585 fprintf (stream
, _("\n\
3586 notes Do print instruction notes.\n"));
3588 #ifdef DEBUG_AARCH64
3589 fprintf (stream
, _("\n\
3590 debug_dump Temp switch for debug trace.\n"));
3591 #endif /* DEBUG_AARCH64 */
3593 fprintf (stream
, _("\n"));