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 memory barrier option operand for DSB <option>nXS|#<imm>. */
1299 aarch64_ext_barrier_dsb_nxs (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1300 aarch64_opnd_info
*info
,
1302 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1303 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1305 /* For the DSB nXS barrier variant immediate is encoded in 2-bit field. */
1306 aarch64_insn field
= extract_field (FLD_CRm_dsb_nxs
, code
, 0);
1307 info
->barrier
= aarch64_barrier_dsb_nxs_options
+ field
;
1311 /* Decode the prefetch operation option operand for e.g.
1312 PRFM <prfop>, [<Xn|SP>{, #<pimm>}]. */
1315 aarch64_ext_prfop (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1316 aarch64_opnd_info
*info
,
1317 aarch64_insn code
, const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1318 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1321 info
->prfop
= aarch64_prfops
+ extract_field (FLD_Rt
, code
, 0);
1325 /* Decode the hint number for an alias taking an operand. Set info->hint_option
1326 to the matching name/value pair in aarch64_hint_options. */
1329 aarch64_ext_hint (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1330 aarch64_opnd_info
*info
,
1332 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1333 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1336 unsigned hint_number
;
1339 hint_number
= extract_fields (code
, 0, 2, FLD_CRm
, FLD_op2
);
1341 for (i
= 0; aarch64_hint_options
[i
].name
!= NULL
; i
++)
1343 if (hint_number
== HINT_VAL (aarch64_hint_options
[i
].value
))
1345 info
->hint_option
= &(aarch64_hint_options
[i
]);
1353 /* Decode the extended register operand for e.g.
1354 STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]. */
1356 aarch64_ext_reg_extended (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1357 aarch64_opnd_info
*info
,
1359 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1360 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1365 info
->reg
.regno
= extract_field (FLD_Rm
, code
, 0);
1367 value
= extract_field (FLD_option
, code
, 0);
1368 info
->shifter
.kind
=
1369 aarch64_get_operand_modifier_from_value (value
, TRUE
/* extend_p */);
1371 info
->shifter
.amount
= extract_field (FLD_imm3
, code
, 0);
1373 /* This makes the constraint checking happy. */
1374 info
->shifter
.operator_present
= 1;
1376 /* Assume inst->operands[0].qualifier has been resolved. */
1377 assert (inst
->operands
[0].qualifier
!= AARCH64_OPND_QLF_NIL
);
1378 info
->qualifier
= AARCH64_OPND_QLF_W
;
1379 if (inst
->operands
[0].qualifier
== AARCH64_OPND_QLF_X
1380 && (info
->shifter
.kind
== AARCH64_MOD_UXTX
1381 || info
->shifter
.kind
== AARCH64_MOD_SXTX
))
1382 info
->qualifier
= AARCH64_OPND_QLF_X
;
1387 /* Decode the shifted register operand for e.g.
1388 SUBS <Xd>, <Xn>, <Xm> {, <shift> #<amount>}. */
1390 aarch64_ext_reg_shifted (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1391 aarch64_opnd_info
*info
,
1393 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1394 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1399 info
->reg
.regno
= extract_field (FLD_Rm
, code
, 0);
1401 value
= extract_field (FLD_shift
, code
, 0);
1402 info
->shifter
.kind
=
1403 aarch64_get_operand_modifier_from_value (value
, FALSE
/* extend_p */);
1404 if (info
->shifter
.kind
== AARCH64_MOD_ROR
1405 && inst
->opcode
->iclass
!= log_shift
)
1406 /* ROR is not available for the shifted register operand in arithmetic
1410 info
->shifter
.amount
= extract_field (FLD_imm6
, code
, 0);
1412 /* This makes the constraint checking happy. */
1413 info
->shifter
.operator_present
= 1;
1418 /* Decode an SVE address [<base>, #<offset>*<factor>, MUL VL],
1419 where <offset> is given by the OFFSET parameter and where <factor> is
1420 1 plus SELF's operand-dependent value. fields[0] specifies the field
1421 that holds <base>. */
1423 aarch64_ext_sve_addr_reg_mul_vl (const aarch64_operand
*self
,
1424 aarch64_opnd_info
*info
, aarch64_insn code
,
1427 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1428 info
->addr
.offset
.imm
= offset
* (1 + get_operand_specific_data (self
));
1429 info
->addr
.offset
.is_reg
= FALSE
;
1430 info
->addr
.writeback
= FALSE
;
1431 info
->addr
.preind
= TRUE
;
1433 info
->shifter
.kind
= AARCH64_MOD_MUL_VL
;
1434 info
->shifter
.amount
= 1;
1435 info
->shifter
.operator_present
= (info
->addr
.offset
.imm
!= 0);
1436 info
->shifter
.amount_present
= FALSE
;
1440 /* Decode an SVE address [<base>, #<simm4>*<factor>, MUL VL],
1441 where <simm4> is a 4-bit signed value and where <factor> is 1 plus
1442 SELF's operand-dependent value. fields[0] specifies the field that
1443 holds <base>. <simm4> is encoded in the SVE_imm4 field. */
1445 aarch64_ext_sve_addr_ri_s4xvl (const aarch64_operand
*self
,
1446 aarch64_opnd_info
*info
, aarch64_insn code
,
1447 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1448 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1452 offset
= extract_field (FLD_SVE_imm4
, code
, 0);
1453 offset
= ((offset
+ 8) & 15) - 8;
1454 return aarch64_ext_sve_addr_reg_mul_vl (self
, info
, code
, offset
);
1457 /* Decode an SVE address [<base>, #<simm6>*<factor>, MUL VL],
1458 where <simm6> is a 6-bit signed value and where <factor> is 1 plus
1459 SELF's operand-dependent value. fields[0] specifies the field that
1460 holds <base>. <simm6> is encoded in the SVE_imm6 field. */
1462 aarch64_ext_sve_addr_ri_s6xvl (const aarch64_operand
*self
,
1463 aarch64_opnd_info
*info
, aarch64_insn code
,
1464 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1465 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1469 offset
= extract_field (FLD_SVE_imm6
, code
, 0);
1470 offset
= (((offset
+ 32) & 63) - 32);
1471 return aarch64_ext_sve_addr_reg_mul_vl (self
, info
, code
, offset
);
1474 /* Decode an SVE address [<base>, #<simm9>*<factor>, MUL VL],
1475 where <simm9> is a 9-bit signed value and where <factor> is 1 plus
1476 SELF's operand-dependent value. fields[0] specifies the field that
1477 holds <base>. <simm9> is encoded in the concatenation of the SVE_imm6
1478 and imm3 fields, with imm3 being the less-significant part. */
1480 aarch64_ext_sve_addr_ri_s9xvl (const aarch64_operand
*self
,
1481 aarch64_opnd_info
*info
,
1483 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1484 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1488 offset
= extract_fields (code
, 0, 2, FLD_SVE_imm6
, FLD_imm3
);
1489 offset
= (((offset
+ 256) & 511) - 256);
1490 return aarch64_ext_sve_addr_reg_mul_vl (self
, info
, code
, offset
);
1493 /* Decode an SVE address [<base>, #<offset> << <shift>], where <offset>
1494 is given by the OFFSET parameter and where <shift> is SELF's operand-
1495 dependent value. fields[0] specifies the base register field <base>. */
1497 aarch64_ext_sve_addr_reg_imm (const aarch64_operand
*self
,
1498 aarch64_opnd_info
*info
, aarch64_insn code
,
1501 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1502 info
->addr
.offset
.imm
= offset
* (1 << get_operand_specific_data (self
));
1503 info
->addr
.offset
.is_reg
= FALSE
;
1504 info
->addr
.writeback
= FALSE
;
1505 info
->addr
.preind
= TRUE
;
1506 info
->shifter
.operator_present
= FALSE
;
1507 info
->shifter
.amount_present
= FALSE
;
1511 /* Decode an SVE address [X<n>, #<SVE_imm4> << <shift>], where <SVE_imm4>
1512 is a 4-bit signed number and where <shift> is SELF's operand-dependent
1513 value. fields[0] specifies the base register field. */
1515 aarch64_ext_sve_addr_ri_s4 (const aarch64_operand
*self
,
1516 aarch64_opnd_info
*info
, aarch64_insn code
,
1517 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1518 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1520 int offset
= sign_extend (extract_field (FLD_SVE_imm4
, code
, 0), 3);
1521 return aarch64_ext_sve_addr_reg_imm (self
, info
, code
, offset
);
1524 /* Decode an SVE address [X<n>, #<SVE_imm6> << <shift>], where <SVE_imm6>
1525 is a 6-bit unsigned number and where <shift> is SELF's operand-dependent
1526 value. fields[0] specifies the base register field. */
1528 aarch64_ext_sve_addr_ri_u6 (const aarch64_operand
*self
,
1529 aarch64_opnd_info
*info
, aarch64_insn code
,
1530 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1531 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1533 int offset
= extract_field (FLD_SVE_imm6
, code
, 0);
1534 return aarch64_ext_sve_addr_reg_imm (self
, info
, code
, offset
);
1537 /* Decode an SVE address [X<n>, X<m>{, LSL #<shift>}], where <shift>
1538 is SELF's operand-dependent value. fields[0] specifies the base
1539 register field and fields[1] specifies the offset register field. */
1541 aarch64_ext_sve_addr_rr_lsl (const aarch64_operand
*self
,
1542 aarch64_opnd_info
*info
, aarch64_insn code
,
1543 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1544 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1548 index_regno
= extract_field (self
->fields
[1], code
, 0);
1549 if (index_regno
== 31 && (self
->flags
& OPD_F_NO_ZR
) != 0)
1552 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1553 info
->addr
.offset
.regno
= index_regno
;
1554 info
->addr
.offset
.is_reg
= TRUE
;
1555 info
->addr
.writeback
= FALSE
;
1556 info
->addr
.preind
= TRUE
;
1557 info
->shifter
.kind
= AARCH64_MOD_LSL
;
1558 info
->shifter
.amount
= get_operand_specific_data (self
);
1559 info
->shifter
.operator_present
= (info
->shifter
.amount
!= 0);
1560 info
->shifter
.amount_present
= (info
->shifter
.amount
!= 0);
1564 /* Decode an SVE address [X<n>, Z<m>.<T>, (S|U)XTW {#<shift>}], where
1565 <shift> is SELF's operand-dependent value. fields[0] specifies the
1566 base register field, fields[1] specifies the offset register field and
1567 fields[2] is a single-bit field that selects SXTW over UXTW. */
1569 aarch64_ext_sve_addr_rz_xtw (const aarch64_operand
*self
,
1570 aarch64_opnd_info
*info
, aarch64_insn code
,
1571 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1572 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1574 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1575 info
->addr
.offset
.regno
= extract_field (self
->fields
[1], code
, 0);
1576 info
->addr
.offset
.is_reg
= TRUE
;
1577 info
->addr
.writeback
= FALSE
;
1578 info
->addr
.preind
= TRUE
;
1579 if (extract_field (self
->fields
[2], code
, 0))
1580 info
->shifter
.kind
= AARCH64_MOD_SXTW
;
1582 info
->shifter
.kind
= AARCH64_MOD_UXTW
;
1583 info
->shifter
.amount
= get_operand_specific_data (self
);
1584 info
->shifter
.operator_present
= TRUE
;
1585 info
->shifter
.amount_present
= (info
->shifter
.amount
!= 0);
1589 /* Decode an SVE address [Z<n>.<T>, #<imm5> << <shift>], where <imm5> is a
1590 5-bit unsigned number and where <shift> is SELF's operand-dependent value.
1591 fields[0] specifies the base register field. */
1593 aarch64_ext_sve_addr_zi_u5 (const aarch64_operand
*self
,
1594 aarch64_opnd_info
*info
, aarch64_insn code
,
1595 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1596 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1598 int offset
= extract_field (FLD_imm5
, code
, 0);
1599 return aarch64_ext_sve_addr_reg_imm (self
, info
, code
, offset
);
1602 /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>{, <modifier> {#<msz>}}],
1603 where <modifier> is given by KIND and where <msz> is a 2-bit unsigned
1604 number. fields[0] specifies the base register field and fields[1]
1605 specifies the offset register field. */
1607 aarch64_ext_sve_addr_zz (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
1608 aarch64_insn code
, enum aarch64_modifier_kind kind
)
1610 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1611 info
->addr
.offset
.regno
= extract_field (self
->fields
[1], code
, 0);
1612 info
->addr
.offset
.is_reg
= TRUE
;
1613 info
->addr
.writeback
= FALSE
;
1614 info
->addr
.preind
= TRUE
;
1615 info
->shifter
.kind
= kind
;
1616 info
->shifter
.amount
= extract_field (FLD_SVE_msz
, code
, 0);
1617 info
->shifter
.operator_present
= (kind
!= AARCH64_MOD_LSL
1618 || info
->shifter
.amount
!= 0);
1619 info
->shifter
.amount_present
= (info
->shifter
.amount
!= 0);
1623 /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>{, LSL #<msz>}], where
1624 <msz> is a 2-bit unsigned number. fields[0] specifies the base register
1625 field and fields[1] specifies the offset register field. */
1627 aarch64_ext_sve_addr_zz_lsl (const aarch64_operand
*self
,
1628 aarch64_opnd_info
*info
, aarch64_insn code
,
1629 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1630 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1632 return aarch64_ext_sve_addr_zz (self
, info
, code
, AARCH64_MOD_LSL
);
1635 /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>, SXTW {#<msz>}], where
1636 <msz> is a 2-bit unsigned number. fields[0] specifies the base register
1637 field and fields[1] specifies the offset register field. */
1639 aarch64_ext_sve_addr_zz_sxtw (const aarch64_operand
*self
,
1640 aarch64_opnd_info
*info
, aarch64_insn code
,
1641 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1642 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1644 return aarch64_ext_sve_addr_zz (self
, info
, code
, AARCH64_MOD_SXTW
);
1647 /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>, UXTW {#<msz>}], where
1648 <msz> is a 2-bit unsigned number. fields[0] specifies the base register
1649 field and fields[1] specifies the offset register field. */
1651 aarch64_ext_sve_addr_zz_uxtw (const aarch64_operand
*self
,
1652 aarch64_opnd_info
*info
, aarch64_insn code
,
1653 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1654 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1656 return aarch64_ext_sve_addr_zz (self
, info
, code
, AARCH64_MOD_UXTW
);
1659 /* Finish decoding an SVE arithmetic immediate, given that INFO already
1660 has the raw field value and that the low 8 bits decode to VALUE. */
1662 decode_sve_aimm (aarch64_opnd_info
*info
, int64_t value
)
1664 info
->shifter
.kind
= AARCH64_MOD_LSL
;
1665 info
->shifter
.amount
= 0;
1666 if (info
->imm
.value
& 0x100)
1669 /* Decode 0x100 as #0, LSL #8. */
1670 info
->shifter
.amount
= 8;
1674 info
->shifter
.operator_present
= (info
->shifter
.amount
!= 0);
1675 info
->shifter
.amount_present
= (info
->shifter
.amount
!= 0);
1676 info
->imm
.value
= value
;
1680 /* Decode an SVE ADD/SUB immediate. */
1682 aarch64_ext_sve_aimm (const aarch64_operand
*self
,
1683 aarch64_opnd_info
*info
, const aarch64_insn code
,
1684 const aarch64_inst
*inst
,
1685 aarch64_operand_error
*errors
)
1687 return (aarch64_ext_imm (self
, info
, code
, inst
, errors
)
1688 && decode_sve_aimm (info
, (uint8_t) info
->imm
.value
));
1691 /* Decode an SVE CPY/DUP immediate. */
1693 aarch64_ext_sve_asimm (const aarch64_operand
*self
,
1694 aarch64_opnd_info
*info
, const aarch64_insn code
,
1695 const aarch64_inst
*inst
,
1696 aarch64_operand_error
*errors
)
1698 return (aarch64_ext_imm (self
, info
, code
, inst
, errors
)
1699 && decode_sve_aimm (info
, (int8_t) info
->imm
.value
));
1702 /* Decode a single-bit immediate that selects between #0.5 and #1.0.
1703 The fields array specifies which field to use. */
1705 aarch64_ext_sve_float_half_one (const aarch64_operand
*self
,
1706 aarch64_opnd_info
*info
, aarch64_insn code
,
1707 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1708 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1710 if (extract_field (self
->fields
[0], code
, 0))
1711 info
->imm
.value
= 0x3f800000;
1713 info
->imm
.value
= 0x3f000000;
1714 info
->imm
.is_fp
= TRUE
;
1718 /* Decode a single-bit immediate that selects between #0.5 and #2.0.
1719 The fields array specifies which field to use. */
1721 aarch64_ext_sve_float_half_two (const aarch64_operand
*self
,
1722 aarch64_opnd_info
*info
, aarch64_insn code
,
1723 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1724 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1726 if (extract_field (self
->fields
[0], code
, 0))
1727 info
->imm
.value
= 0x40000000;
1729 info
->imm
.value
= 0x3f000000;
1730 info
->imm
.is_fp
= TRUE
;
1734 /* Decode a single-bit immediate that selects between #0.0 and #1.0.
1735 The fields array specifies which field to use. */
1737 aarch64_ext_sve_float_zero_one (const aarch64_operand
*self
,
1738 aarch64_opnd_info
*info
, aarch64_insn code
,
1739 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1740 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1742 if (extract_field (self
->fields
[0], code
, 0))
1743 info
->imm
.value
= 0x3f800000;
1745 info
->imm
.value
= 0x0;
1746 info
->imm
.is_fp
= TRUE
;
1750 /* Decode Zn[MM], where MM has a 7-bit triangular encoding. The fields
1751 array specifies which field to use for Zn. MM is encoded in the
1752 concatenation of imm5 and SVE_tszh, with imm5 being the less
1753 significant part. */
1755 aarch64_ext_sve_index (const aarch64_operand
*self
,
1756 aarch64_opnd_info
*info
, aarch64_insn code
,
1757 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1758 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1762 info
->reglane
.regno
= extract_field (self
->fields
[0], code
, 0);
1763 val
= extract_fields (code
, 0, 2, FLD_SVE_tszh
, FLD_imm5
);
1764 if ((val
& 31) == 0)
1766 while ((val
& 1) == 0)
1768 info
->reglane
.index
= val
/ 2;
1772 /* Decode a logical immediate for the MOV alias of SVE DUPM. */
1774 aarch64_ext_sve_limm_mov (const aarch64_operand
*self
,
1775 aarch64_opnd_info
*info
, const aarch64_insn code
,
1776 const aarch64_inst
*inst
,
1777 aarch64_operand_error
*errors
)
1779 int esize
= aarch64_get_qualifier_esize (inst
->operands
[0].qualifier
);
1780 return (aarch64_ext_limm (self
, info
, code
, inst
, errors
)
1781 && aarch64_sve_dupm_mov_immediate_p (info
->imm
.value
, esize
));
1784 /* Decode Zn[MM], where Zn occupies the least-significant part of the field
1785 and where MM occupies the most-significant part. The operand-dependent
1786 value specifies the number of bits in Zn. */
1788 aarch64_ext_sve_quad_index (const aarch64_operand
*self
,
1789 aarch64_opnd_info
*info
, aarch64_insn code
,
1790 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1791 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1793 unsigned int reg_bits
= get_operand_specific_data (self
);
1794 unsigned int val
= extract_all_fields (self
, code
);
1795 info
->reglane
.regno
= val
& ((1 << reg_bits
) - 1);
1796 info
->reglane
.index
= val
>> reg_bits
;
1800 /* Decode {Zn.<T> - Zm.<T>}. The fields array specifies which field
1801 to use for Zn. The opcode-dependent value specifies the number
1802 of registers in the list. */
1804 aarch64_ext_sve_reglist (const aarch64_operand
*self
,
1805 aarch64_opnd_info
*info
, aarch64_insn code
,
1806 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1807 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1809 info
->reglist
.first_regno
= extract_field (self
->fields
[0], code
, 0);
1810 info
->reglist
.num_regs
= get_opcode_dependent_value (inst
->opcode
);
1814 /* Decode <pattern>{, MUL #<amount>}. The fields array specifies which
1815 fields to use for <pattern>. <amount> - 1 is encoded in the SVE_imm4
1818 aarch64_ext_sve_scale (const aarch64_operand
*self
,
1819 aarch64_opnd_info
*info
, aarch64_insn code
,
1820 const aarch64_inst
*inst
, aarch64_operand_error
*errors
)
1824 if (!aarch64_ext_imm (self
, info
, code
, inst
, errors
))
1826 val
= extract_field (FLD_SVE_imm4
, code
, 0);
1827 info
->shifter
.kind
= AARCH64_MOD_MUL
;
1828 info
->shifter
.amount
= val
+ 1;
1829 info
->shifter
.operator_present
= (val
!= 0);
1830 info
->shifter
.amount_present
= (val
!= 0);
1834 /* Return the top set bit in VALUE, which is expected to be relatively
1837 get_top_bit (uint64_t value
)
1839 while ((value
& -value
) != value
)
1840 value
-= value
& -value
;
1844 /* Decode an SVE shift-left immediate. */
1846 aarch64_ext_sve_shlimm (const aarch64_operand
*self
,
1847 aarch64_opnd_info
*info
, const aarch64_insn code
,
1848 const aarch64_inst
*inst
, aarch64_operand_error
*errors
)
1850 if (!aarch64_ext_imm (self
, info
, code
, inst
, errors
)
1851 || info
->imm
.value
== 0)
1854 info
->imm
.value
-= get_top_bit (info
->imm
.value
);
1858 /* Decode an SVE shift-right immediate. */
1860 aarch64_ext_sve_shrimm (const aarch64_operand
*self
,
1861 aarch64_opnd_info
*info
, const aarch64_insn code
,
1862 const aarch64_inst
*inst
, aarch64_operand_error
*errors
)
1864 if (!aarch64_ext_imm (self
, info
, code
, inst
, errors
)
1865 || info
->imm
.value
== 0)
1868 info
->imm
.value
= get_top_bit (info
->imm
.value
) * 2 - info
->imm
.value
;
1872 /* Bitfields that are commonly used to encode certain operands' information
1873 may be partially used as part of the base opcode in some instructions.
1874 For example, the bit 1 of the field 'size' in
1875 FCVTXN <Vb><d>, <Va><n>
1876 is actually part of the base opcode, while only size<0> is available
1877 for encoding the register type. Another example is the AdvSIMD
1878 instruction ORR (register), in which the field 'size' is also used for
1879 the base opcode, leaving only the field 'Q' available to encode the
1880 vector register arrangement specifier '8B' or '16B'.
1882 This function tries to deduce the qualifier from the value of partially
1883 constrained field(s). Given the VALUE of such a field or fields, the
1884 qualifiers CANDIDATES and the MASK (indicating which bits are valid for
1885 operand encoding), the function returns the matching qualifier or
1886 AARCH64_OPND_QLF_NIL if nothing matches.
1888 N.B. CANDIDATES is a group of possible qualifiers that are valid for
1889 one operand; it has a maximum of AARCH64_MAX_QLF_SEQ_NUM qualifiers and
1890 may end with AARCH64_OPND_QLF_NIL. */
1892 static enum aarch64_opnd_qualifier
1893 get_qualifier_from_partial_encoding (aarch64_insn value
,
1894 const enum aarch64_opnd_qualifier
* \
1899 DEBUG_TRACE ("enter with value: %d, mask: %d", (int)value
, (int)mask
);
1900 for (i
= 0; i
< AARCH64_MAX_QLF_SEQ_NUM
; ++i
)
1902 aarch64_insn standard_value
;
1903 if (candidates
[i
] == AARCH64_OPND_QLF_NIL
)
1905 standard_value
= aarch64_get_qualifier_standard_value (candidates
[i
]);
1906 if ((standard_value
& mask
) == (value
& mask
))
1907 return candidates
[i
];
1909 return AARCH64_OPND_QLF_NIL
;
1912 /* Given a list of qualifier sequences, return all possible valid qualifiers
1913 for operand IDX in QUALIFIERS.
1914 Assume QUALIFIERS is an array whose length is large enough. */
1917 get_operand_possible_qualifiers (int idx
,
1918 const aarch64_opnd_qualifier_seq_t
*list
,
1919 enum aarch64_opnd_qualifier
*qualifiers
)
1922 for (i
= 0; i
< AARCH64_MAX_QLF_SEQ_NUM
; ++i
)
1923 if ((qualifiers
[i
] = list
[i
][idx
]) == AARCH64_OPND_QLF_NIL
)
1927 /* Decode the size Q field for e.g. SHADD.
1928 We tag one operand with the qualifer according to the code;
1929 whether the qualifier is valid for this opcode or not, it is the
1930 duty of the semantic checking. */
1933 decode_sizeq (aarch64_inst
*inst
)
1936 enum aarch64_opnd_qualifier qualifier
;
1938 aarch64_insn value
, mask
;
1939 enum aarch64_field_kind fld_sz
;
1940 enum aarch64_opnd_qualifier candidates
[AARCH64_MAX_QLF_SEQ_NUM
];
1942 if (inst
->opcode
->iclass
== asisdlse
1943 || inst
->opcode
->iclass
== asisdlsep
1944 || inst
->opcode
->iclass
== asisdlso
1945 || inst
->opcode
->iclass
== asisdlsop
)
1946 fld_sz
= FLD_vldst_size
;
1951 value
= extract_fields (code
, inst
->opcode
->mask
, 2, fld_sz
, FLD_Q
);
1952 /* Obtain the info that which bits of fields Q and size are actually
1953 available for operand encoding. Opcodes like FMAXNM and FMLA have
1954 size[1] unavailable. */
1955 mask
= extract_fields (~inst
->opcode
->mask
, 0, 2, fld_sz
, FLD_Q
);
1957 /* The index of the operand we are going to tag a qualifier and the qualifer
1958 itself are reasoned from the value of the size and Q fields and the
1959 possible valid qualifier lists. */
1960 idx
= aarch64_select_operand_for_sizeq_field_coding (inst
->opcode
);
1961 DEBUG_TRACE ("key idx: %d", idx
);
1963 /* For most related instruciton, size:Q are fully available for operand
1967 inst
->operands
[idx
].qualifier
= get_vreg_qualifier_from_value (value
);
1971 get_operand_possible_qualifiers (idx
, inst
->opcode
->qualifiers_list
,
1973 #ifdef DEBUG_AARCH64
1977 for (i
= 0; candidates
[i
] != AARCH64_OPND_QLF_NIL
1978 && i
< AARCH64_MAX_QLF_SEQ_NUM
; ++i
)
1979 DEBUG_TRACE ("qualifier %d: %s", i
,
1980 aarch64_get_qualifier_name(candidates
[i
]));
1981 DEBUG_TRACE ("%d, %d", (int)value
, (int)mask
);
1983 #endif /* DEBUG_AARCH64 */
1985 qualifier
= get_qualifier_from_partial_encoding (value
, candidates
, mask
);
1987 if (qualifier
== AARCH64_OPND_QLF_NIL
)
1990 inst
->operands
[idx
].qualifier
= qualifier
;
1994 /* Decode size[0]:Q, i.e. bit 22 and bit 30, for
1995 e.g. FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>. */
1998 decode_asimd_fcvt (aarch64_inst
*inst
)
2000 aarch64_field field
= {0, 0};
2002 enum aarch64_opnd_qualifier qualifier
;
2004 gen_sub_field (FLD_size
, 0, 1, &field
);
2005 value
= extract_field_2 (&field
, inst
->value
, 0);
2006 qualifier
= value
== 0 ? AARCH64_OPND_QLF_V_4S
2007 : AARCH64_OPND_QLF_V_2D
;
2008 switch (inst
->opcode
->op
)
2012 /* FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>. */
2013 inst
->operands
[1].qualifier
= qualifier
;
2017 /* FCVTL<Q> <Vd>.<Ta>, <Vn>.<Tb>. */
2018 inst
->operands
[0].qualifier
= qualifier
;
2028 /* Decode size[0], i.e. bit 22, for
2029 e.g. FCVTXN <Vb><d>, <Va><n>. */
2032 decode_asisd_fcvtxn (aarch64_inst
*inst
)
2034 aarch64_field field
= {0, 0};
2035 gen_sub_field (FLD_size
, 0, 1, &field
);
2036 if (!extract_field_2 (&field
, inst
->value
, 0))
2038 inst
->operands
[0].qualifier
= AARCH64_OPND_QLF_S_S
;
2042 /* Decode the 'opc' field for e.g. FCVT <Dd>, <Sn>. */
2044 decode_fcvt (aarch64_inst
*inst
)
2046 enum aarch64_opnd_qualifier qualifier
;
2048 const aarch64_field field
= {15, 2};
2051 value
= extract_field_2 (&field
, inst
->value
, 0);
2054 case 0: qualifier
= AARCH64_OPND_QLF_S_S
; break;
2055 case 1: qualifier
= AARCH64_OPND_QLF_S_D
; break;
2056 case 3: qualifier
= AARCH64_OPND_QLF_S_H
; break;
2059 inst
->operands
[0].qualifier
= qualifier
;
2064 /* Do miscellaneous decodings that are not common enough to be driven by
2068 do_misc_decoding (aarch64_inst
*inst
)
2071 switch (inst
->opcode
->op
)
2074 return decode_fcvt (inst
);
2080 return decode_asimd_fcvt (inst
);
2083 return decode_asisd_fcvtxn (inst
);
2087 value
= extract_field (FLD_SVE_Pn
, inst
->value
, 0);
2088 return (value
== extract_field (FLD_SVE_Pm
, inst
->value
, 0)
2089 && value
== extract_field (FLD_SVE_Pg4_10
, inst
->value
, 0));
2092 return (extract_field (FLD_SVE_Zd
, inst
->value
, 0)
2093 == extract_field (FLD_SVE_Zm_16
, inst
->value
, 0));
2096 /* Index must be zero. */
2097 value
= extract_fields (inst
->value
, 0, 2, FLD_SVE_tszh
, FLD_imm5
);
2098 return value
> 0 && value
<= 16 && value
== (value
& -value
);
2101 return (extract_field (FLD_SVE_Zn
, inst
->value
, 0)
2102 == extract_field (FLD_SVE_Zm_16
, inst
->value
, 0));
2105 /* Index must be nonzero. */
2106 value
= extract_fields (inst
->value
, 0, 2, FLD_SVE_tszh
, FLD_imm5
);
2107 return value
> 0 && value
!= (value
& -value
);
2110 return (extract_field (FLD_SVE_Pd
, inst
->value
, 0)
2111 == extract_field (FLD_SVE_Pm
, inst
->value
, 0));
2113 case OP_MOVZS_P_P_P
:
2115 return (extract_field (FLD_SVE_Pn
, inst
->value
, 0)
2116 == extract_field (FLD_SVE_Pm
, inst
->value
, 0));
2118 case OP_NOTS_P_P_P_Z
:
2119 case OP_NOT_P_P_P_Z
:
2120 return (extract_field (FLD_SVE_Pm
, inst
->value
, 0)
2121 == extract_field (FLD_SVE_Pg4_10
, inst
->value
, 0));
2128 /* Opcodes that have fields shared by multiple operands are usually flagged
2129 with flags. In this function, we detect such flags, decode the related
2130 field(s) and store the information in one of the related operands. The
2131 'one' operand is not any operand but one of the operands that can
2132 accommadate all the information that has been decoded. */
2135 do_special_decoding (aarch64_inst
*inst
)
2139 /* Condition for truly conditional executed instructions, e.g. b.cond. */
2140 if (inst
->opcode
->flags
& F_COND
)
2142 value
= extract_field (FLD_cond2
, inst
->value
, 0);
2143 inst
->cond
= get_cond_from_value (value
);
2146 if (inst
->opcode
->flags
& F_SF
)
2148 idx
= select_operand_for_sf_field_coding (inst
->opcode
);
2149 value
= extract_field (FLD_sf
, inst
->value
, 0);
2150 inst
->operands
[idx
].qualifier
= get_greg_qualifier_from_value (value
);
2151 if ((inst
->opcode
->flags
& F_N
)
2152 && extract_field (FLD_N
, inst
->value
, 0) != value
)
2156 if (inst
->opcode
->flags
& F_LSE_SZ
)
2158 idx
= select_operand_for_sf_field_coding (inst
->opcode
);
2159 value
= extract_field (FLD_lse_sz
, inst
->value
, 0);
2160 inst
->operands
[idx
].qualifier
= get_greg_qualifier_from_value (value
);
2162 /* size:Q fields. */
2163 if (inst
->opcode
->flags
& F_SIZEQ
)
2164 return decode_sizeq (inst
);
2166 if (inst
->opcode
->flags
& F_FPTYPE
)
2168 idx
= select_operand_for_fptype_field_coding (inst
->opcode
);
2169 value
= extract_field (FLD_type
, inst
->value
, 0);
2172 case 0: inst
->operands
[idx
].qualifier
= AARCH64_OPND_QLF_S_S
; break;
2173 case 1: inst
->operands
[idx
].qualifier
= AARCH64_OPND_QLF_S_D
; break;
2174 case 3: inst
->operands
[idx
].qualifier
= AARCH64_OPND_QLF_S_H
; break;
2179 if (inst
->opcode
->flags
& F_SSIZE
)
2181 /* N.B. some opcodes like FCMGT <V><d>, <V><n>, #0 have the size[1] as part
2182 of the base opcode. */
2184 enum aarch64_opnd_qualifier candidates
[AARCH64_MAX_QLF_SEQ_NUM
];
2185 idx
= select_operand_for_scalar_size_field_coding (inst
->opcode
);
2186 value
= extract_field (FLD_size
, inst
->value
, inst
->opcode
->mask
);
2187 mask
= extract_field (FLD_size
, ~inst
->opcode
->mask
, 0);
2188 /* For most related instruciton, the 'size' field is fully available for
2189 operand encoding. */
2191 inst
->operands
[idx
].qualifier
= get_sreg_qualifier_from_value (value
);
2194 get_operand_possible_qualifiers (idx
, inst
->opcode
->qualifiers_list
,
2196 inst
->operands
[idx
].qualifier
2197 = get_qualifier_from_partial_encoding (value
, candidates
, mask
);
2201 if (inst
->opcode
->flags
& F_T
)
2203 /* Num of consecutive '0's on the right side of imm5<3:0>. */
2206 assert (aarch64_get_operand_class (inst
->opcode
->operands
[0])
2207 == AARCH64_OPND_CLASS_SIMD_REG
);
2218 val
= extract_field (FLD_imm5
, inst
->value
, 0);
2219 while ((val
& 0x1) == 0 && ++num
<= 3)
2223 Q
= (unsigned) extract_field (FLD_Q
, inst
->value
, inst
->opcode
->mask
);
2224 inst
->operands
[0].qualifier
=
2225 get_vreg_qualifier_from_value ((num
<< 1) | Q
);
2228 if (inst
->opcode
->flags
& F_GPRSIZE_IN_Q
)
2230 /* Use Rt to encode in the case of e.g.
2231 STXP <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}]. */
2232 idx
= aarch64_operand_index (inst
->opcode
->operands
, AARCH64_OPND_Rt
);
2235 /* Otherwise use the result operand, which has to be a integer
2237 assert (aarch64_get_operand_class (inst
->opcode
->operands
[0])
2238 == AARCH64_OPND_CLASS_INT_REG
);
2241 assert (idx
== 0 || idx
== 1);
2242 value
= extract_field (FLD_Q
, inst
->value
, 0);
2243 inst
->operands
[idx
].qualifier
= get_greg_qualifier_from_value (value
);
2246 if (inst
->opcode
->flags
& F_LDS_SIZE
)
2248 aarch64_field field
= {0, 0};
2249 assert (aarch64_get_operand_class (inst
->opcode
->operands
[0])
2250 == AARCH64_OPND_CLASS_INT_REG
);
2251 gen_sub_field (FLD_opc
, 0, 1, &field
);
2252 value
= extract_field_2 (&field
, inst
->value
, 0);
2253 inst
->operands
[0].qualifier
2254 = value
? AARCH64_OPND_QLF_W
: AARCH64_OPND_QLF_X
;
2257 /* Miscellaneous decoding; done as the last step. */
2258 if (inst
->opcode
->flags
& F_MISC
)
2259 return do_misc_decoding (inst
);
2264 /* Converters converting a real opcode instruction to its alias form. */
2266 /* ROR <Wd>, <Ws>, #<shift>
2268 EXTR <Wd>, <Ws>, <Ws>, #<shift>. */
2270 convert_extr_to_ror (aarch64_inst
*inst
)
2272 if (inst
->operands
[1].reg
.regno
== inst
->operands
[2].reg
.regno
)
2274 copy_operand_info (inst
, 2, 3);
2275 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
2281 /* UXTL<Q> <Vd>.<Ta>, <Vn>.<Tb>
2283 USHLL<Q> <Vd>.<Ta>, <Vn>.<Tb>, #0. */
2285 convert_shll_to_xtl (aarch64_inst
*inst
)
2287 if (inst
->operands
[2].imm
.value
== 0)
2289 inst
->operands
[2].type
= AARCH64_OPND_NIL
;
2296 UBFM <Xd>, <Xn>, #<shift>, #63.
2298 LSR <Xd>, <Xn>, #<shift>. */
2300 convert_bfm_to_sr (aarch64_inst
*inst
)
2304 imms
= inst
->operands
[3].imm
.value
;
2305 val
= inst
->operands
[2].qualifier
== AARCH64_OPND_QLF_imm_0_31
? 31 : 63;
2308 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
2315 /* Convert MOV to ORR. */
2317 convert_orr_to_mov (aarch64_inst
*inst
)
2319 /* MOV <Vd>.<T>, <Vn>.<T>
2321 ORR <Vd>.<T>, <Vn>.<T>, <Vn>.<T>. */
2322 if (inst
->operands
[1].reg
.regno
== inst
->operands
[2].reg
.regno
)
2324 inst
->operands
[2].type
= AARCH64_OPND_NIL
;
2330 /* When <imms> >= <immr>, the instruction written:
2331 SBFX <Xd>, <Xn>, #<lsb>, #<width>
2333 SBFM <Xd>, <Xn>, #<lsb>, #(<lsb>+<width>-1). */
2336 convert_bfm_to_bfx (aarch64_inst
*inst
)
2340 immr
= inst
->operands
[2].imm
.value
;
2341 imms
= inst
->operands
[3].imm
.value
;
2345 inst
->operands
[2].imm
.value
= lsb
;
2346 inst
->operands
[3].imm
.value
= imms
+ 1 - lsb
;
2347 /* The two opcodes have different qualifiers for
2348 the immediate operands; reset to help the checking. */
2349 reset_operand_qualifier (inst
, 2);
2350 reset_operand_qualifier (inst
, 3);
2357 /* When <imms> < <immr>, the instruction written:
2358 SBFIZ <Xd>, <Xn>, #<lsb>, #<width>
2360 SBFM <Xd>, <Xn>, #((64-<lsb>)&0x3f), #(<width>-1). */
2363 convert_bfm_to_bfi (aarch64_inst
*inst
)
2365 int64_t immr
, imms
, val
;
2367 immr
= inst
->operands
[2].imm
.value
;
2368 imms
= inst
->operands
[3].imm
.value
;
2369 val
= inst
->operands
[2].qualifier
== AARCH64_OPND_QLF_imm_0_31
? 32 : 64;
2372 inst
->operands
[2].imm
.value
= (val
- immr
) & (val
- 1);
2373 inst
->operands
[3].imm
.value
= imms
+ 1;
2374 /* The two opcodes have different qualifiers for
2375 the immediate operands; reset to help the checking. */
2376 reset_operand_qualifier (inst
, 2);
2377 reset_operand_qualifier (inst
, 3);
2384 /* The instruction written:
2385 BFC <Xd>, #<lsb>, #<width>
2387 BFM <Xd>, XZR, #((64-<lsb>)&0x3f), #(<width>-1). */
2390 convert_bfm_to_bfc (aarch64_inst
*inst
)
2392 int64_t immr
, imms
, val
;
2394 /* Should have been assured by the base opcode value. */
2395 assert (inst
->operands
[1].reg
.regno
== 0x1f);
2397 immr
= inst
->operands
[2].imm
.value
;
2398 imms
= inst
->operands
[3].imm
.value
;
2399 val
= inst
->operands
[2].qualifier
== AARCH64_OPND_QLF_imm_0_31
? 32 : 64;
2402 /* Drop XZR from the second operand. */
2403 copy_operand_info (inst
, 1, 2);
2404 copy_operand_info (inst
, 2, 3);
2405 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
2407 /* Recalculate the immediates. */
2408 inst
->operands
[1].imm
.value
= (val
- immr
) & (val
- 1);
2409 inst
->operands
[2].imm
.value
= imms
+ 1;
2411 /* The two opcodes have different qualifiers for the operands; reset to
2412 help the checking. */
2413 reset_operand_qualifier (inst
, 1);
2414 reset_operand_qualifier (inst
, 2);
2415 reset_operand_qualifier (inst
, 3);
2423 /* The instruction written:
2424 LSL <Xd>, <Xn>, #<shift>
2426 UBFM <Xd>, <Xn>, #((64-<shift>)&0x3f), #(63-<shift>). */
2429 convert_ubfm_to_lsl (aarch64_inst
*inst
)
2431 int64_t immr
= inst
->operands
[2].imm
.value
;
2432 int64_t imms
= inst
->operands
[3].imm
.value
;
2434 = inst
->operands
[2].qualifier
== AARCH64_OPND_QLF_imm_0_31
? 31 : 63;
2436 if ((immr
== 0 && imms
== val
) || immr
== imms
+ 1)
2438 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
2439 inst
->operands
[2].imm
.value
= val
- imms
;
2446 /* CINC <Wd>, <Wn>, <cond>
2448 CSINC <Wd>, <Wn>, <Wn>, invert(<cond>)
2449 where <cond> is not AL or NV. */
2452 convert_from_csel (aarch64_inst
*inst
)
2454 if (inst
->operands
[1].reg
.regno
== inst
->operands
[2].reg
.regno
2455 && (inst
->operands
[3].cond
->value
& 0xe) != 0xe)
2457 copy_operand_info (inst
, 2, 3);
2458 inst
->operands
[2].cond
= get_inverted_cond (inst
->operands
[3].cond
);
2459 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
2465 /* CSET <Wd>, <cond>
2467 CSINC <Wd>, WZR, WZR, invert(<cond>)
2468 where <cond> is not AL or NV. */
2471 convert_csinc_to_cset (aarch64_inst
*inst
)
2473 if (inst
->operands
[1].reg
.regno
== 0x1f
2474 && inst
->operands
[2].reg
.regno
== 0x1f
2475 && (inst
->operands
[3].cond
->value
& 0xe) != 0xe)
2477 copy_operand_info (inst
, 1, 3);
2478 inst
->operands
[1].cond
= get_inverted_cond (inst
->operands
[3].cond
);
2479 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
2480 inst
->operands
[2].type
= AARCH64_OPND_NIL
;
2488 MOVZ <Wd>, #<imm16>, LSL #<shift>.
2490 A disassembler may output ORR, MOVZ and MOVN as a MOV mnemonic, except when
2491 ORR has an immediate that could be generated by a MOVZ or MOVN instruction,
2492 or where a MOVN has an immediate that could be encoded by MOVZ, or where
2493 MOVZ/MOVN #0 have a shift amount other than LSL #0, in which case the
2494 machine-instruction mnemonic must be used. */
2497 convert_movewide_to_mov (aarch64_inst
*inst
)
2499 uint64_t value
= inst
->operands
[1].imm
.value
;
2500 /* MOVZ/MOVN #0 have a shift amount other than LSL #0. */
2501 if (value
== 0 && inst
->operands
[1].shifter
.amount
!= 0)
2503 inst
->operands
[1].type
= AARCH64_OPND_IMM_MOV
;
2504 inst
->operands
[1].shifter
.kind
= AARCH64_MOD_NONE
;
2505 value
<<= inst
->operands
[1].shifter
.amount
;
2506 /* As an alias convertor, it has to be clear that the INST->OPCODE
2507 is the opcode of the real instruction. */
2508 if (inst
->opcode
->op
== OP_MOVN
)
2510 int is32
= inst
->operands
[0].qualifier
== AARCH64_OPND_QLF_W
;
2512 /* A MOVN has an immediate that could be encoded by MOVZ. */
2513 if (aarch64_wide_constant_p (value
, is32
, NULL
))
2516 inst
->operands
[1].imm
.value
= value
;
2517 inst
->operands
[1].shifter
.amount
= 0;
2523 ORR <Wd>, WZR, #<imm>.
2525 A disassembler may output ORR, MOVZ and MOVN as a MOV mnemonic, except when
2526 ORR has an immediate that could be generated by a MOVZ or MOVN instruction,
2527 or where a MOVN has an immediate that could be encoded by MOVZ, or where
2528 MOVZ/MOVN #0 have a shift amount other than LSL #0, in which case the
2529 machine-instruction mnemonic must be used. */
2532 convert_movebitmask_to_mov (aarch64_inst
*inst
)
2537 /* Should have been assured by the base opcode value. */
2538 assert (inst
->operands
[1].reg
.regno
== 0x1f);
2539 copy_operand_info (inst
, 1, 2);
2540 is32
= inst
->operands
[0].qualifier
== AARCH64_OPND_QLF_W
;
2541 inst
->operands
[1].type
= AARCH64_OPND_IMM_MOV
;
2542 value
= inst
->operands
[1].imm
.value
;
2543 /* ORR has an immediate that could be generated by a MOVZ or MOVN
2545 if (inst
->operands
[0].reg
.regno
!= 0x1f
2546 && (aarch64_wide_constant_p (value
, is32
, NULL
)
2547 || aarch64_wide_constant_p (~value
, is32
, NULL
)))
2550 inst
->operands
[2].type
= AARCH64_OPND_NIL
;
2554 /* Some alias opcodes are disassembled by being converted from their real-form.
2555 N.B. INST->OPCODE is the real opcode rather than the alias. */
2558 convert_to_alias (aarch64_inst
*inst
, const aarch64_opcode
*alias
)
2564 return convert_bfm_to_sr (inst
);
2566 return convert_ubfm_to_lsl (inst
);
2570 return convert_from_csel (inst
);
2573 return convert_csinc_to_cset (inst
);
2577 return convert_bfm_to_bfx (inst
);
2581 return convert_bfm_to_bfi (inst
);
2583 return convert_bfm_to_bfc (inst
);
2585 return convert_orr_to_mov (inst
);
2586 case OP_MOV_IMM_WIDE
:
2587 case OP_MOV_IMM_WIDEN
:
2588 return convert_movewide_to_mov (inst
);
2589 case OP_MOV_IMM_LOG
:
2590 return convert_movebitmask_to_mov (inst
);
2592 return convert_extr_to_ror (inst
);
2597 return convert_shll_to_xtl (inst
);
2604 aarch64_opcode_decode (const aarch64_opcode
*, const aarch64_insn
,
2605 aarch64_inst
*, int, aarch64_operand_error
*errors
);
2607 /* Given the instruction information in *INST, check if the instruction has
2608 any alias form that can be used to represent *INST. If the answer is yes,
2609 update *INST to be in the form of the determined alias. */
2611 /* In the opcode description table, the following flags are used in opcode
2612 entries to help establish the relations between the real and alias opcodes:
2614 F_ALIAS: opcode is an alias
2615 F_HAS_ALIAS: opcode has alias(es)
2618 F_P3: Disassembly preference priority 1-3 (the larger the
2619 higher). If nothing is specified, it is the priority
2620 0 by default, i.e. the lowest priority.
2622 Although the relation between the machine and the alias instructions are not
2623 explicitly described, it can be easily determined from the base opcode
2624 values, masks and the flags F_ALIAS and F_HAS_ALIAS in their opcode
2625 description entries:
2627 The mask of an alias opcode must be equal to or a super-set (i.e. more
2628 constrained) of that of the aliased opcode; so is the base opcode value.
2630 if (opcode_has_alias (real) && alias_opcode_p (opcode)
2631 && (opcode->mask & real->mask) == real->mask
2632 && (real->mask & opcode->opcode) == (real->mask & real->opcode))
2633 then OPCODE is an alias of, and only of, the REAL instruction
2635 The alias relationship is forced flat-structured to keep related algorithm
2636 simple; an opcode entry cannot be flagged with both F_ALIAS and F_HAS_ALIAS.
2638 During the disassembling, the decoding decision tree (in
2639 opcodes/aarch64-dis-2.c) always returns an machine instruction opcode entry;
2640 if the decoding of such a machine instruction succeeds (and -Mno-aliases is
2641 not specified), the disassembler will check whether there is any alias
2642 instruction exists for this real instruction. If there is, the disassembler
2643 will try to disassemble the 32-bit binary again using the alias's rule, or
2644 try to convert the IR to the form of the alias. In the case of the multiple
2645 aliases, the aliases are tried one by one from the highest priority
2646 (currently the flag F_P3) to the lowest priority (no priority flag), and the
2647 first succeeds first adopted.
2649 You may ask why there is a need for the conversion of IR from one form to
2650 another in handling certain aliases. This is because on one hand it avoids
2651 adding more operand code to handle unusual encoding/decoding; on other
2652 hand, during the disassembling, the conversion is an effective approach to
2653 check the condition of an alias (as an alias may be adopted only if certain
2654 conditions are met).
2656 In order to speed up the alias opcode lookup, aarch64-gen has preprocessed
2657 aarch64_opcode_table and generated aarch64_find_alias_opcode and
2658 aarch64_find_next_alias_opcode (in opcodes/aarch64-dis-2.c) to help. */
2661 determine_disassembling_preference (struct aarch64_inst
*inst
,
2662 aarch64_operand_error
*errors
)
2664 const aarch64_opcode
*opcode
;
2665 const aarch64_opcode
*alias
;
2667 opcode
= inst
->opcode
;
2669 /* This opcode does not have an alias, so use itself. */
2670 if (!opcode_has_alias (opcode
))
2673 alias
= aarch64_find_alias_opcode (opcode
);
2676 #ifdef DEBUG_AARCH64
2679 const aarch64_opcode
*tmp
= alias
;
2680 printf ("#### LIST orderd: ");
2683 printf ("%s, ", tmp
->name
);
2684 tmp
= aarch64_find_next_alias_opcode (tmp
);
2688 #endif /* DEBUG_AARCH64 */
2690 for (; alias
; alias
= aarch64_find_next_alias_opcode (alias
))
2692 DEBUG_TRACE ("try %s", alias
->name
);
2693 assert (alias_opcode_p (alias
) || opcode_has_alias (opcode
));
2695 /* An alias can be a pseudo opcode which will never be used in the
2696 disassembly, e.g. BIC logical immediate is such a pseudo opcode
2698 if (pseudo_opcode_p (alias
))
2700 DEBUG_TRACE ("skip pseudo %s", alias
->name
);
2704 if ((inst
->value
& alias
->mask
) != alias
->opcode
)
2706 DEBUG_TRACE ("skip %s as base opcode not match", alias
->name
);
2710 if (!AARCH64_CPU_HAS_FEATURE (arch_variant
, *alias
->avariant
))
2712 DEBUG_TRACE ("skip %s: we're missing features", alias
->name
);
2716 /* No need to do any complicated transformation on operands, if the alias
2717 opcode does not have any operand. */
2718 if (aarch64_num_of_operands (alias
) == 0 && alias
->opcode
== inst
->value
)
2720 DEBUG_TRACE ("succeed with 0-operand opcode %s", alias
->name
);
2721 aarch64_replace_opcode (inst
, alias
);
2724 if (alias
->flags
& F_CONV
)
2727 memcpy (©
, inst
, sizeof (aarch64_inst
));
2728 /* ALIAS is the preference as long as the instruction can be
2729 successfully converted to the form of ALIAS. */
2730 if (convert_to_alias (©
, alias
) == 1)
2732 aarch64_replace_opcode (©
, alias
);
2733 assert (aarch64_match_operands_constraint (©
, NULL
));
2734 DEBUG_TRACE ("succeed with %s via conversion", alias
->name
);
2735 memcpy (inst
, ©
, sizeof (aarch64_inst
));
2741 /* Directly decode the alias opcode. */
2743 memset (&temp
, '\0', sizeof (aarch64_inst
));
2744 if (aarch64_opcode_decode (alias
, inst
->value
, &temp
, 1, errors
) == 1)
2746 DEBUG_TRACE ("succeed with %s via direct decoding", alias
->name
);
2747 memcpy (inst
, &temp
, sizeof (aarch64_inst
));
2754 /* Some instructions (including all SVE ones) use the instruction class
2755 to describe how a qualifiers_list index is represented in the instruction
2756 encoding. If INST is such an instruction, decode the appropriate fields
2757 and fill in the operand qualifiers accordingly. Return true if no
2758 problems are found. */
2761 aarch64_decode_variant_using_iclass (aarch64_inst
*inst
)
2766 switch (inst
->opcode
->iclass
)
2769 variant
= extract_fields (inst
->value
, 0, 2, FLD_size
, FLD_SVE_M_14
);
2773 i
= extract_fields (inst
->value
, 0, 2, FLD_SVE_tszh
, FLD_imm5
);
2776 while ((i
& 1) == 0)
2784 /* Pick the smallest applicable element size. */
2785 if ((inst
->value
& 0x20600) == 0x600)
2787 else if ((inst
->value
& 0x20400) == 0x400)
2789 else if ((inst
->value
& 0x20000) == 0)
2796 /* sve_misc instructions have only a single variant. */
2800 variant
= extract_fields (inst
->value
, 0, 2, FLD_size
, FLD_SVE_M_16
);
2804 variant
= extract_field (FLD_SVE_M_4
, inst
->value
, 0);
2807 case sve_shift_pred
:
2808 i
= extract_fields (inst
->value
, 0, 2, FLD_SVE_tszh
, FLD_SVE_tszl_8
);
2819 case sve_shift_unpred
:
2820 i
= extract_fields (inst
->value
, 0, 2, FLD_SVE_tszh
, FLD_SVE_tszl_19
);
2824 variant
= extract_field (FLD_size
, inst
->value
, 0);
2830 variant
= extract_field (FLD_size
, inst
->value
, 0);
2834 i
= extract_field (FLD_size
, inst
->value
, 0);
2842 variant
= extract_field (FLD_SVE_sz
, inst
->value
, 0);
2846 variant
= extract_field (FLD_SVE_sz2
, inst
->value
, 0);
2850 i
= extract_field (FLD_SVE_size
, inst
->value
, 0);
2857 /* Ignore low bit of this field since that is set in the opcode for
2858 instructions of this iclass. */
2859 i
= (extract_field (FLD_size
, inst
->value
, 0) & 2);
2863 case sve_shift_tsz_bhsd
:
2864 i
= extract_fields (inst
->value
, 0, 2, FLD_SVE_tszh
, FLD_SVE_tszl_19
);
2874 case sve_size_tsz_bhs
:
2875 i
= extract_fields (inst
->value
, 0, 2, FLD_SVE_sz
, FLD_SVE_tszl_19
);
2887 case sve_shift_tsz_hsd
:
2888 i
= extract_fields (inst
->value
, 0, 2, FLD_SVE_sz
, FLD_SVE_tszl_19
);
2899 /* No mapping between instruction class and qualifiers. */
2903 for (i
= 0; i
< AARCH64_MAX_OPND_NUM
; ++i
)
2904 inst
->operands
[i
].qualifier
= inst
->opcode
->qualifiers_list
[variant
][i
];
2907 /* Decode the CODE according to OPCODE; fill INST. Return 0 if the decoding
2908 fails, which meanes that CODE is not an instruction of OPCODE; otherwise
2911 If OPCODE has alias(es) and NOALIASES_P is 0, an alias opcode may be
2912 determined and used to disassemble CODE; this is done just before the
2916 aarch64_opcode_decode (const aarch64_opcode
*opcode
, const aarch64_insn code
,
2917 aarch64_inst
*inst
, int noaliases_p
,
2918 aarch64_operand_error
*errors
)
2922 DEBUG_TRACE ("enter with %s", opcode
->name
);
2924 assert (opcode
&& inst
);
2927 memset (inst
, '\0', sizeof (aarch64_inst
));
2929 /* Check the base opcode. */
2930 if ((code
& opcode
->mask
) != (opcode
->opcode
& opcode
->mask
))
2932 DEBUG_TRACE ("base opcode match FAIL");
2936 inst
->opcode
= opcode
;
2939 /* Assign operand codes and indexes. */
2940 for (i
= 0; i
< AARCH64_MAX_OPND_NUM
; ++i
)
2942 if (opcode
->operands
[i
] == AARCH64_OPND_NIL
)
2944 inst
->operands
[i
].type
= opcode
->operands
[i
];
2945 inst
->operands
[i
].idx
= i
;
2948 /* Call the opcode decoder indicated by flags. */
2949 if (opcode_has_special_coder (opcode
) && do_special_decoding (inst
) == 0)
2951 DEBUG_TRACE ("opcode flag-based decoder FAIL");
2955 /* Possibly use the instruction class to determine the correct
2957 if (!aarch64_decode_variant_using_iclass (inst
))
2959 DEBUG_TRACE ("iclass-based decoder FAIL");
2963 /* Call operand decoders. */
2964 for (i
= 0; i
< AARCH64_MAX_OPND_NUM
; ++i
)
2966 const aarch64_operand
*opnd
;
2967 enum aarch64_opnd type
;
2969 type
= opcode
->operands
[i
];
2970 if (type
== AARCH64_OPND_NIL
)
2972 opnd
= &aarch64_operands
[type
];
2973 if (operand_has_extractor (opnd
)
2974 && (! aarch64_extract_operand (opnd
, &inst
->operands
[i
], code
, inst
,
2977 DEBUG_TRACE ("operand decoder FAIL at operand %d", i
);
2982 /* If the opcode has a verifier, then check it now. */
2983 if (opcode
->verifier
2984 && opcode
->verifier (inst
, code
, 0, FALSE
, errors
, NULL
) != ERR_OK
)
2986 DEBUG_TRACE ("operand verifier FAIL");
2990 /* Match the qualifiers. */
2991 if (aarch64_match_operands_constraint (inst
, NULL
) == 1)
2993 /* Arriving here, the CODE has been determined as a valid instruction
2994 of OPCODE and *INST has been filled with information of this OPCODE
2995 instruction. Before the return, check if the instruction has any
2996 alias and should be disassembled in the form of its alias instead.
2997 If the answer is yes, *INST will be updated. */
2999 determine_disassembling_preference (inst
, errors
);
3000 DEBUG_TRACE ("SUCCESS");
3005 DEBUG_TRACE ("constraint matching FAIL");
3012 /* This does some user-friendly fix-up to *INST. It is currently focus on
3013 the adjustment of qualifiers to help the printed instruction
3014 recognized/understood more easily. */
3017 user_friendly_fixup (aarch64_inst
*inst
)
3019 switch (inst
->opcode
->iclass
)
3022 /* TBNZ Xn|Wn, #uimm6, label
3023 Test and Branch Not Zero: conditionally jumps to label if bit number
3024 uimm6 in register Xn is not zero. The bit number implies the width of
3025 the register, which may be written and should be disassembled as Wn if
3026 uimm is less than 32. Limited to a branch offset range of +/- 32KiB.
3028 if (inst
->operands
[1].imm
.value
< 32)
3029 inst
->operands
[0].qualifier
= AARCH64_OPND_QLF_W
;
3035 /* Decode INSN and fill in *INST the instruction information. An alias
3036 opcode may be filled in *INSN if NOALIASES_P is FALSE. Return zero on
3040 aarch64_decode_insn (aarch64_insn insn
, aarch64_inst
*inst
,
3041 bfd_boolean noaliases_p
,
3042 aarch64_operand_error
*errors
)
3044 const aarch64_opcode
*opcode
= aarch64_opcode_lookup (insn
);
3046 #ifdef DEBUG_AARCH64
3049 const aarch64_opcode
*tmp
= opcode
;
3051 DEBUG_TRACE ("opcode lookup:");
3054 aarch64_verbose (" %s", tmp
->name
);
3055 tmp
= aarch64_find_next_opcode (tmp
);
3058 #endif /* DEBUG_AARCH64 */
3060 /* A list of opcodes may have been found, as aarch64_opcode_lookup cannot
3061 distinguish some opcodes, e.g. SSHR and MOVI, which almost share the same
3062 opcode field and value, apart from the difference that one of them has an
3063 extra field as part of the opcode, but such a field is used for operand
3064 encoding in other opcode(s) ('immh' in the case of the example). */
3065 while (opcode
!= NULL
)
3067 /* But only one opcode can be decoded successfully for, as the
3068 decoding routine will check the constraint carefully. */
3069 if (aarch64_opcode_decode (opcode
, insn
, inst
, noaliases_p
, errors
) == 1)
3071 opcode
= aarch64_find_next_opcode (opcode
);
3077 /* Print operands. */
3080 print_operands (bfd_vma pc
, const aarch64_opcode
*opcode
,
3081 const aarch64_opnd_info
*opnds
, struct disassemble_info
*info
,
3082 bfd_boolean
*has_notes
)
3085 int i
, pcrel_p
, num_printed
;
3086 for (i
= 0, num_printed
= 0; i
< AARCH64_MAX_OPND_NUM
; ++i
)
3089 /* We regard the opcode operand info more, however we also look into
3090 the inst->operands to support the disassembling of the optional
3092 The two operand code should be the same in all cases, apart from
3093 when the operand can be optional. */
3094 if (opcode
->operands
[i
] == AARCH64_OPND_NIL
3095 || opnds
[i
].type
== AARCH64_OPND_NIL
)
3098 /* Generate the operand string in STR. */
3099 aarch64_print_operand (str
, sizeof (str
), pc
, opcode
, opnds
, i
, &pcrel_p
,
3100 &info
->target
, ¬es
, arch_variant
);
3102 /* Print the delimiter (taking account of omitted operand(s)). */
3104 (*info
->fprintf_func
) (info
->stream
, "%s",
3105 num_printed
++ == 0 ? "\t" : ", ");
3107 /* Print the operand. */
3109 (*info
->print_address_func
) (info
->target
, info
);
3111 (*info
->fprintf_func
) (info
->stream
, "%s", str
);
3114 if (notes
&& !no_notes
)
3117 (*info
->fprintf_func
) (info
->stream
, " // note: %s", notes
);
3121 /* Set NAME to a copy of INST's mnemonic with the "." suffix removed. */
3124 remove_dot_suffix (char *name
, const aarch64_inst
*inst
)
3129 ptr
= strchr (inst
->opcode
->name
, '.');
3130 assert (ptr
&& inst
->cond
);
3131 len
= ptr
- inst
->opcode
->name
;
3133 strncpy (name
, inst
->opcode
->name
, len
);
3137 /* Print the instruction mnemonic name. */
3140 print_mnemonic_name (const aarch64_inst
*inst
, struct disassemble_info
*info
)
3142 if (inst
->opcode
->flags
& F_COND
)
3144 /* For instructions that are truly conditionally executed, e.g. b.cond,
3145 prepare the full mnemonic name with the corresponding condition
3149 remove_dot_suffix (name
, inst
);
3150 (*info
->fprintf_func
) (info
->stream
, "%s.%s", name
, inst
->cond
->names
[0]);
3153 (*info
->fprintf_func
) (info
->stream
, "%s", inst
->opcode
->name
);
3156 /* Decide whether we need to print a comment after the operands of
3157 instruction INST. */
3160 print_comment (const aarch64_inst
*inst
, struct disassemble_info
*info
)
3162 if (inst
->opcode
->flags
& F_COND
)
3165 unsigned int i
, num_conds
;
3167 remove_dot_suffix (name
, inst
);
3168 num_conds
= ARRAY_SIZE (inst
->cond
->names
);
3169 for (i
= 1; i
< num_conds
&& inst
->cond
->names
[i
]; ++i
)
3170 (*info
->fprintf_func
) (info
->stream
, "%s %s.%s",
3171 i
== 1 ? " //" : ",",
3172 name
, inst
->cond
->names
[i
]);
3176 /* Build notes from verifiers into a string for printing. */
3179 print_verifier_notes (aarch64_operand_error
*detail
,
3180 struct disassemble_info
*info
)
3185 /* The output of the verifier cannot be a fatal error, otherwise the assembly
3186 would not have succeeded. We can safely ignore these. */
3187 assert (detail
->non_fatal
);
3188 assert (detail
->error
);
3190 /* If there are multiple verifier messages, concat them up to 1k. */
3191 (*info
->fprintf_func
) (info
->stream
, " // note: %s", detail
->error
);
3192 if (detail
->index
>= 0)
3193 (*info
->fprintf_func
) (info
->stream
, " at operand %d", detail
->index
+ 1);
3196 /* Print the instruction according to *INST. */
3199 print_aarch64_insn (bfd_vma pc
, const aarch64_inst
*inst
,
3200 const aarch64_insn code
,
3201 struct disassemble_info
*info
,
3202 aarch64_operand_error
*mismatch_details
)
3204 bfd_boolean has_notes
= FALSE
;
3206 print_mnemonic_name (inst
, info
);
3207 print_operands (pc
, inst
->opcode
, inst
->operands
, info
, &has_notes
);
3208 print_comment (inst
, info
);
3210 /* We've already printed a note, not enough space to print more so exit.
3211 Usually notes shouldn't overlap so it shouldn't happen that we have a note
3212 from a register and instruction at the same time. */
3216 /* Always run constraint verifiers, this is needed because constraints need to
3217 maintain a global state regardless of whether the instruction has the flag
3219 enum err_type result
= verify_constraints (inst
, code
, pc
, FALSE
,
3220 mismatch_details
, &insn_sequence
);
3228 print_verifier_notes (mismatch_details
, info
);
3235 /* Entry-point of the instruction disassembler and printer. */
3238 print_insn_aarch64_word (bfd_vma pc
,
3240 struct disassemble_info
*info
,
3241 aarch64_operand_error
*errors
)
3243 static const char *err_msg
[ERR_NR_ENTRIES
+1] =
3246 [ERR_UND
] = "undefined",
3247 [ERR_UNP
] = "unpredictable",
3254 info
->insn_info_valid
= 1;
3255 info
->branch_delay_insns
= 0;
3256 info
->data_size
= 0;
3260 if (info
->flags
& INSN_HAS_RELOC
)
3261 /* If the instruction has a reloc associated with it, then
3262 the offset field in the instruction will actually be the
3263 addend for the reloc. (If we are using REL type relocs).
3264 In such cases, we can ignore the pc when computing
3265 addresses, since the addend is not currently pc-relative. */
3268 ret
= aarch64_decode_insn (word
, &inst
, no_aliases
, errors
);
3270 if (((word
>> 21) & 0x3ff) == 1)
3272 /* RESERVED for ALES. */
3273 assert (ret
!= ERR_OK
);
3282 /* Handle undefined instructions. */
3283 info
->insn_type
= dis_noninsn
;
3284 (*info
->fprintf_func
) (info
->stream
,".inst\t0x%08x ; %s",
3285 word
, err_msg
[ret
]);
3288 user_friendly_fixup (&inst
);
3289 print_aarch64_insn (pc
, &inst
, word
, info
, errors
);
3296 /* Disallow mapping symbols ($x, $d etc) from
3297 being displayed in symbol relative addresses. */
3300 aarch64_symbol_is_valid (asymbol
* sym
,
3301 struct disassemble_info
* info ATTRIBUTE_UNUSED
)
3308 name
= bfd_asymbol_name (sym
);
3312 || (name
[1] != 'x' && name
[1] != 'd')
3313 || (name
[2] != '\0' && name
[2] != '.'));
3316 /* Print data bytes on INFO->STREAM. */
3319 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED
,
3321 struct disassemble_info
*info
,
3322 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
3324 switch (info
->bytes_per_chunk
)
3327 info
->fprintf_func (info
->stream
, ".byte\t0x%02x", word
);
3330 info
->fprintf_func (info
->stream
, ".short\t0x%04x", word
);
3333 info
->fprintf_func (info
->stream
, ".word\t0x%08x", word
);
3340 /* Try to infer the code or data type from a symbol.
3341 Returns nonzero if *MAP_TYPE was set. */
3344 get_sym_code_type (struct disassemble_info
*info
, int n
,
3345 enum map_type
*map_type
)
3348 elf_symbol_type
*es
;
3352 /* If the symbol is in a different section, ignore it. */
3353 if (info
->section
!= NULL
&& info
->section
!= info
->symtab
[n
]->section
)
3356 if (n
>= info
->symtab_size
)
3359 as
= info
->symtab
[n
];
3360 if (bfd_asymbol_flavour (as
) != bfd_target_elf_flavour
)
3362 es
= (elf_symbol_type
*) as
;
3364 type
= ELF_ST_TYPE (es
->internal_elf_sym
.st_info
);
3366 /* If the symbol has function type then use that. */
3367 if (type
== STT_FUNC
)
3369 *map_type
= MAP_INSN
;
3373 /* Check for mapping symbols. */
3374 name
= bfd_asymbol_name(info
->symtab
[n
]);
3376 && (name
[1] == 'x' || name
[1] == 'd')
3377 && (name
[2] == '\0' || name
[2] == '.'))
3379 *map_type
= (name
[1] == 'x' ? MAP_INSN
: MAP_DATA
);
3386 /* Set the feature bits in arch_variant in order to get the correct disassembly
3387 for the chosen architecture variant.
3389 Currently we only restrict disassembly for Armv8-R and otherwise enable all
3390 non-R-profile features. */
3392 select_aarch64_variant (unsigned mach
)
3396 case bfd_mach_aarch64_8R
:
3397 arch_variant
= AARCH64_ARCH_V8_R
;
3400 arch_variant
= AARCH64_ANY
& ~(AARCH64_FEATURE_V8_R
);
3404 /* Entry-point of the AArch64 disassembler. */
3407 print_insn_aarch64 (bfd_vma pc
,
3408 struct disassemble_info
*info
)
3410 bfd_byte buffer
[INSNLEN
];
3412 void (*printer
) (bfd_vma
, uint32_t, struct disassemble_info
*,
3413 aarch64_operand_error
*);
3414 bfd_boolean found
= FALSE
;
3415 unsigned int size
= 4;
3417 aarch64_operand_error errors
;
3418 static bfd_boolean set_features
;
3420 if (info
->disassembler_options
)
3422 set_default_aarch64_dis_options (info
);
3424 parse_aarch64_dis_options (info
->disassembler_options
);
3426 /* To avoid repeated parsing of these options, we remove them here. */
3427 info
->disassembler_options
= NULL
;
3432 select_aarch64_variant (info
->mach
);
3433 set_features
= TRUE
;
3436 /* Aarch64 instructions are always little-endian */
3437 info
->endian_code
= BFD_ENDIAN_LITTLE
;
3439 /* Default to DATA. A text section is required by the ABI to contain an
3440 INSN mapping symbol at the start. A data section has no such
3441 requirement, hence if no mapping symbol is found the section must
3442 contain only data. This however isn't very useful if the user has
3443 fully stripped the binaries. If this is the case use the section
3444 attributes to determine the default. If we have no section default to
3445 INSN as well, as we may be disassembling some raw bytes on a baremetal
3446 HEX file or similar. */
3447 enum map_type type
= MAP_DATA
;
3448 if ((info
->section
&& info
->section
->flags
& SEC_CODE
) || !info
->section
)
3451 /* First check the full symtab for a mapping symbol, even if there
3452 are no usable non-mapping symbols for this address. */
3453 if (info
->symtab_size
!= 0
3454 && bfd_asymbol_flavour (*info
->symtab
) == bfd_target_elf_flavour
)
3457 bfd_vma addr
, section_vma
= 0;
3458 bfd_boolean can_use_search_opt_p
;
3461 if (pc
<= last_mapping_addr
)
3462 last_mapping_sym
= -1;
3464 /* Start scanning at the start of the function, or wherever
3465 we finished last time. */
3466 n
= info
->symtab_pos
+ 1;
3468 /* If the last stop offset is different from the current one it means we
3469 are disassembling a different glob of bytes. As such the optimization
3470 would not be safe and we should start over. */
3471 can_use_search_opt_p
= last_mapping_sym
>= 0
3472 && info
->stop_offset
== last_stop_offset
;
3474 if (n
>= last_mapping_sym
&& can_use_search_opt_p
)
3475 n
= last_mapping_sym
;
3477 /* Look down while we haven't passed the location being disassembled.
3478 The reason for this is that there's no defined order between a symbol
3479 and an mapping symbol that may be at the same address. We may have to
3480 look at least one position ahead. */
3481 for (; n
< info
->symtab_size
; n
++)
3483 addr
= bfd_asymbol_value (info
->symtab
[n
]);
3486 if (get_sym_code_type (info
, n
, &type
))
3495 n
= info
->symtab_pos
;
3496 if (n
>= last_mapping_sym
&& can_use_search_opt_p
)
3497 n
= last_mapping_sym
;
3499 /* No mapping symbol found at this address. Look backwards
3500 for a preceeding one, but don't go pass the section start
3501 otherwise a data section with no mapping symbol can pick up
3502 a text mapping symbol of a preceeding section. The documentation
3503 says section can be NULL, in which case we will seek up all the
3506 section_vma
= info
->section
->vma
;
3510 addr
= bfd_asymbol_value (info
->symtab
[n
]);
3511 if (addr
< section_vma
)
3514 if (get_sym_code_type (info
, n
, &type
))
3523 last_mapping_sym
= last_sym
;
3525 last_stop_offset
= info
->stop_offset
;
3527 /* Look a little bit ahead to see if we should print out
3528 less than four bytes of data. If there's a symbol,
3529 mapping or otherwise, after two bytes then don't
3531 if (last_type
== MAP_DATA
)
3533 size
= 4 - (pc
& 3);
3534 for (n
= last_sym
+ 1; n
< info
->symtab_size
; n
++)
3536 addr
= bfd_asymbol_value (info
->symtab
[n
]);
3539 if (addr
- pc
< size
)
3544 /* If the next symbol is after three bytes, we need to
3545 print only part of the data, so that we can use either
3548 size
= (pc
& 1) ? 1 : 2;
3554 /* PR 10263: Disassemble data if requested to do so by the user. */
3555 if (last_type
== MAP_DATA
&& ((info
->flags
& DISASSEMBLE_DATA
) == 0))
3557 /* size was set above. */
3558 info
->bytes_per_chunk
= size
;
3559 info
->display_endian
= info
->endian
;
3560 printer
= print_insn_data
;
3564 info
->bytes_per_chunk
= size
= INSNLEN
;
3565 info
->display_endian
= info
->endian_code
;
3566 printer
= print_insn_aarch64_word
;
3569 status
= (*info
->read_memory_func
) (pc
, buffer
, size
, info
);
3572 (*info
->memory_error_func
) (status
, pc
, info
);
3576 data
= bfd_get_bits (buffer
, size
* 8,
3577 info
->display_endian
== BFD_ENDIAN_BIG
);
3579 (*printer
) (pc
, data
, info
, &errors
);
3585 print_aarch64_disassembler_options (FILE *stream
)
3587 fprintf (stream
, _("\n\
3588 The following AARCH64 specific disassembler options are supported for use\n\
3589 with the -M switch (multiple options should be separated by commas):\n"));
3591 fprintf (stream
, _("\n\
3592 no-aliases Don't print instruction aliases.\n"));
3594 fprintf (stream
, _("\n\
3595 aliases Do print instruction aliases.\n"));
3597 fprintf (stream
, _("\n\
3598 no-notes Don't print instruction notes.\n"));
3600 fprintf (stream
, _("\n\
3601 notes Do print instruction notes.\n"));
3603 #ifdef DEBUG_AARCH64
3604 fprintf (stream
, _("\n\
3605 debug_dump Temp switch for debug trace.\n"));
3606 #endif /* DEBUG_AARCH64 */
3608 fprintf (stream
, _("\n"));