1 /* aarch64-dis.c -- AArch64 disassembler.
2 Copyright (C) 2009-2022 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/>. */
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 (startswith (option
, "no-aliases"))
67 if (startswith (option
, "aliases"))
73 if (startswith (option
, "no-notes"))
79 if (startswith (option
, "notes"))
86 if (startswith (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
);
162 /* Extract the value of all fields in SELF->fields from instruction CODE.
163 The least significant bit comes from the final field. */
166 extract_all_fields (const aarch64_operand
*self
, aarch64_insn code
)
170 enum aarch64_field_kind kind
;
173 for (i
= 0; i
< ARRAY_SIZE (self
->fields
) && self
->fields
[i
] != FLD_NIL
; ++i
)
175 kind
= self
->fields
[i
];
176 value
<<= fields
[kind
].width
;
177 value
|= extract_field (kind
, code
, 0);
182 /* Sign-extend bit I of VALUE. */
183 static inline uint64_t
184 sign_extend (aarch64_insn value
, unsigned i
)
190 sign
= (uint64_t) 1 << i
;
191 return ((ret
& (sign
+ sign
- 1)) ^ sign
) - sign
;
194 /* N.B. the following inline helpfer functions create a dependency on the
195 order of operand qualifier enumerators. */
197 /* Given VALUE, return qualifier for a general purpose register. */
198 static inline enum aarch64_opnd_qualifier
199 get_greg_qualifier_from_value (aarch64_insn value
)
201 enum aarch64_opnd_qualifier qualifier
= AARCH64_OPND_QLF_W
+ value
;
203 && aarch64_get_qualifier_standard_value (qualifier
) == value
);
207 /* Given VALUE, return qualifier for a vector register. This does not support
208 decoding instructions that accept the 2H vector type. */
210 static inline enum aarch64_opnd_qualifier
211 get_vreg_qualifier_from_value (aarch64_insn value
)
213 enum aarch64_opnd_qualifier qualifier
= AARCH64_OPND_QLF_V_8B
+ value
;
215 /* Instructions using vector type 2H should not call this function. Skip over
217 if (qualifier
>= AARCH64_OPND_QLF_V_2H
)
221 && aarch64_get_qualifier_standard_value (qualifier
) == value
);
225 /* Given VALUE, return qualifier for an FP or AdvSIMD scalar register. */
226 static inline enum aarch64_opnd_qualifier
227 get_sreg_qualifier_from_value (aarch64_insn value
)
229 enum aarch64_opnd_qualifier qualifier
= AARCH64_OPND_QLF_S_B
+ value
;
232 && aarch64_get_qualifier_standard_value (qualifier
) == value
);
236 /* Given the instruction in *INST which is probably half way through the
237 decoding and our caller wants to know the expected qualifier for operand
238 I. Return such a qualifier if we can establish it; otherwise return
239 AARCH64_OPND_QLF_NIL. */
241 static aarch64_opnd_qualifier_t
242 get_expected_qualifier (const aarch64_inst
*inst
, int i
)
244 aarch64_opnd_qualifier_seq_t qualifiers
;
245 /* Should not be called if the qualifier is known. */
246 assert (inst
->operands
[i
].qualifier
== AARCH64_OPND_QLF_NIL
);
247 if (aarch64_find_best_match (inst
, inst
->opcode
->qualifiers_list
,
249 return qualifiers
[i
];
251 return AARCH64_OPND_QLF_NIL
;
254 /* Operand extractors. */
257 aarch64_ext_none (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
258 aarch64_opnd_info
*info ATTRIBUTE_UNUSED
,
259 const aarch64_insn code ATTRIBUTE_UNUSED
,
260 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
261 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
267 aarch64_ext_regno (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
268 const aarch64_insn code
,
269 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
270 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
272 info
->reg
.regno
= extract_field (self
->fields
[0], code
, 0);
277 aarch64_ext_regno_pair (const aarch64_operand
*self ATTRIBUTE_UNUSED
, aarch64_opnd_info
*info
,
278 const aarch64_insn code ATTRIBUTE_UNUSED
,
279 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
280 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
282 assert (info
->idx
== 1
284 info
->reg
.regno
= inst
->operands
[info
->idx
- 1].reg
.regno
+ 1;
288 /* e.g. IC <ic_op>{, <Xt>}. */
290 aarch64_ext_regrt_sysins (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
291 const aarch64_insn code
,
292 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
293 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
295 info
->reg
.regno
= extract_field (self
->fields
[0], code
, 0);
296 assert (info
->idx
== 1
297 && (aarch64_get_operand_class (inst
->operands
[0].type
)
298 == AARCH64_OPND_CLASS_SYSTEM
));
299 /* This will make the constraint checking happy and more importantly will
300 help the disassembler determine whether this operand is optional or
302 info
->present
= aarch64_sys_ins_reg_has_xt (inst
->operands
[0].sysins_op
);
307 /* e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]. */
309 aarch64_ext_reglane (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
310 const aarch64_insn code
,
311 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
312 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
315 info
->reglane
.regno
= extract_field (self
->fields
[0], code
,
318 /* Index and/or type. */
319 if (inst
->opcode
->iclass
== asisdone
320 || inst
->opcode
->iclass
== asimdins
)
322 if (info
->type
== AARCH64_OPND_En
323 && inst
->opcode
->operands
[0] == AARCH64_OPND_Ed
)
326 /* index2 for e.g. INS <Vd>.<Ts>[<index1>], <Vn>.<Ts>[<index2>]. */
327 assert (info
->idx
== 1); /* Vn */
328 aarch64_insn value
= extract_field (FLD_imm4
, code
, 0);
329 /* Depend on AARCH64_OPND_Ed to determine the qualifier. */
330 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
331 shift
= get_logsz (aarch64_get_qualifier_esize (info
->qualifier
));
332 info
->reglane
.index
= value
>> shift
;
336 /* index and type for e.g. DUP <V><d>, <Vn>.<T>[<index>].
344 aarch64_insn value
= extract_field (FLD_imm5
, code
, 0);
345 while (++pos
<= 3 && (value
& 0x1) == 0)
349 info
->qualifier
= get_sreg_qualifier_from_value (pos
);
350 info
->reglane
.index
= (unsigned) (value
>> 1);
353 else if (inst
->opcode
->iclass
== dotproduct
)
355 /* Need information in other operand(s) to help decoding. */
356 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
357 switch (info
->qualifier
)
359 case AARCH64_OPND_QLF_S_4B
:
360 case AARCH64_OPND_QLF_S_2H
:
362 info
->reglane
.index
= extract_fields (code
, 0, 2, FLD_H
, FLD_L
);
363 info
->reglane
.regno
&= 0x1f;
369 else if (inst
->opcode
->iclass
== cryptosm3
)
371 /* index for e.g. SM3TT2A <Vd>.4S, <Vn>.4S, <Vm>S[<imm2>]. */
372 info
->reglane
.index
= extract_field (FLD_SM3_imm2
, code
, 0);
376 /* Index only for e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
377 or SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]. */
379 /* Need information in other operand(s) to help decoding. */
380 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
381 switch (info
->qualifier
)
383 case AARCH64_OPND_QLF_S_H
:
384 if (info
->type
== AARCH64_OPND_Em16
)
387 info
->reglane
.index
= extract_fields (code
, 0, 3, FLD_H
, FLD_L
,
389 info
->reglane
.regno
&= 0xf;
394 info
->reglane
.index
= extract_fields (code
, 0, 2, FLD_H
, FLD_L
);
397 case AARCH64_OPND_QLF_S_S
:
399 info
->reglane
.index
= extract_fields (code
, 0, 2, FLD_H
, FLD_L
);
401 case AARCH64_OPND_QLF_S_D
:
403 info
->reglane
.index
= extract_field (FLD_H
, code
, 0);
409 if (inst
->opcode
->op
== OP_FCMLA_ELEM
410 && info
->qualifier
!= AARCH64_OPND_QLF_S_H
)
412 /* Complex operand takes two elements. */
413 if (info
->reglane
.index
& 1)
415 info
->reglane
.index
/= 2;
423 aarch64_ext_reglist (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
424 const aarch64_insn code
,
425 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
426 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
429 info
->reglist
.first_regno
= extract_field (self
->fields
[0], code
, 0);
431 info
->reglist
.num_regs
= extract_field (FLD_len
, code
, 0) + 1;
435 /* Decode Rt and opcode fields of Vt in AdvSIMD load/store instructions. */
437 aarch64_ext_ldst_reglist (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
438 aarch64_opnd_info
*info
, const aarch64_insn code
,
439 const aarch64_inst
*inst
,
440 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
443 /* Number of elements in each structure to be loaded/stored. */
444 unsigned expected_num
= get_opcode_dependent_value (inst
->opcode
);
448 unsigned is_reserved
;
450 unsigned num_elements
;
466 info
->reglist
.first_regno
= extract_field (FLD_Rt
, code
, 0);
468 value
= extract_field (FLD_opcode
, code
, 0);
469 /* PR 21595: Check for a bogus value. */
470 if (value
>= ARRAY_SIZE (data
))
472 if (expected_num
!= data
[value
].num_elements
|| data
[value
].is_reserved
)
474 info
->reglist
.num_regs
= data
[value
].num_regs
;
479 /* Decode Rt and S fields of Vt in AdvSIMD load single structure to all
480 lanes instructions. */
482 aarch64_ext_ldst_reglist_r (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
483 aarch64_opnd_info
*info
, const aarch64_insn code
,
484 const aarch64_inst
*inst
,
485 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
490 info
->reglist
.first_regno
= extract_field (FLD_Rt
, code
, 0);
492 value
= extract_field (FLD_S
, code
, 0);
494 /* Number of registers is equal to the number of elements in
495 each structure to be loaded/stored. */
496 info
->reglist
.num_regs
= get_opcode_dependent_value (inst
->opcode
);
497 assert (info
->reglist
.num_regs
>= 1 && info
->reglist
.num_regs
<= 4);
499 /* Except when it is LD1R. */
500 if (info
->reglist
.num_regs
== 1 && value
== (aarch64_insn
) 1)
501 info
->reglist
.num_regs
= 2;
506 /* Decode Q, opcode<2:1>, S, size and Rt fields of Vt in AdvSIMD
507 load/store single element instructions. */
509 aarch64_ext_ldst_elemlist (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
510 aarch64_opnd_info
*info
, const aarch64_insn code
,
511 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
512 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
514 aarch64_field field
= {0, 0};
515 aarch64_insn QSsize
; /* fields Q:S:size. */
516 aarch64_insn opcodeh2
; /* opcode<2:1> */
519 info
->reglist
.first_regno
= extract_field (FLD_Rt
, code
, 0);
521 /* Decode the index, opcode<2:1> and size. */
522 gen_sub_field (FLD_asisdlso_opcode
, 1, 2, &field
);
523 opcodeh2
= extract_field_2 (&field
, code
, 0);
524 QSsize
= extract_fields (code
, 0, 3, FLD_Q
, FLD_S
, FLD_vldst_size
);
528 info
->qualifier
= AARCH64_OPND_QLF_S_B
;
529 /* Index encoded in "Q:S:size". */
530 info
->reglist
.index
= QSsize
;
536 info
->qualifier
= AARCH64_OPND_QLF_S_H
;
537 /* Index encoded in "Q:S:size<1>". */
538 info
->reglist
.index
= QSsize
>> 1;
541 if ((QSsize
>> 1) & 0x1)
544 if ((QSsize
& 0x1) == 0)
546 info
->qualifier
= AARCH64_OPND_QLF_S_S
;
547 /* Index encoded in "Q:S". */
548 info
->reglist
.index
= QSsize
>> 2;
552 if (extract_field (FLD_S
, code
, 0))
555 info
->qualifier
= AARCH64_OPND_QLF_S_D
;
556 /* Index encoded in "Q". */
557 info
->reglist
.index
= QSsize
>> 3;
564 info
->reglist
.has_index
= 1;
565 info
->reglist
.num_regs
= 0;
566 /* Number of registers is equal to the number of elements in
567 each structure to be loaded/stored. */
568 info
->reglist
.num_regs
= get_opcode_dependent_value (inst
->opcode
);
569 assert (info
->reglist
.num_regs
>= 1 && info
->reglist
.num_regs
<= 4);
574 /* Decode fields immh:immb and/or Q for e.g.
575 SSHR <Vd>.<T>, <Vn>.<T>, #<shift>
576 or SSHR <V><d>, <V><n>, #<shift>. */
579 aarch64_ext_advsimd_imm_shift (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
580 aarch64_opnd_info
*info
, const aarch64_insn code
,
581 const aarch64_inst
*inst
,
582 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
585 aarch64_insn Q
, imm
, immh
;
586 enum aarch64_insn_class iclass
= inst
->opcode
->iclass
;
588 immh
= extract_field (FLD_immh
, code
, 0);
591 imm
= extract_fields (code
, 0, 2, FLD_immh
, FLD_immb
);
593 /* Get highest set bit in immh. */
594 while (--pos
>= 0 && (immh
& 0x8) == 0)
597 assert ((iclass
== asimdshf
|| iclass
== asisdshf
)
598 && (info
->type
== AARCH64_OPND_IMM_VLSR
599 || info
->type
== AARCH64_OPND_IMM_VLSL
));
601 if (iclass
== asimdshf
)
603 Q
= extract_field (FLD_Q
, code
, 0);
605 0000 x SEE AdvSIMD modified immediate
615 get_vreg_qualifier_from_value ((pos
<< 1) | (int) Q
);
618 info
->qualifier
= get_sreg_qualifier_from_value (pos
);
620 if (info
->type
== AARCH64_OPND_IMM_VLSR
)
622 0000 SEE AdvSIMD modified immediate
623 0001 (16-UInt(immh:immb))
624 001x (32-UInt(immh:immb))
625 01xx (64-UInt(immh:immb))
626 1xxx (128-UInt(immh:immb)) */
627 info
->imm
.value
= (16 << pos
) - imm
;
631 0000 SEE AdvSIMD modified immediate
632 0001 (UInt(immh:immb)-8)
633 001x (UInt(immh:immb)-16)
634 01xx (UInt(immh:immb)-32)
635 1xxx (UInt(immh:immb)-64) */
636 info
->imm
.value
= imm
- (8 << pos
);
641 /* Decode shift immediate for e.g. sshr (imm). */
643 aarch64_ext_shll_imm (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
644 aarch64_opnd_info
*info
, const aarch64_insn code
,
645 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
646 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
650 val
= extract_field (FLD_size
, code
, 0);
653 case 0: imm
= 8; break;
654 case 1: imm
= 16; break;
655 case 2: imm
= 32; break;
656 default: return false;
658 info
->imm
.value
= imm
;
662 /* Decode imm for e.g. BFM <Wd>, <Wn>, #<immr>, #<imms>.
663 value in the field(s) will be extracted as unsigned immediate value. */
665 aarch64_ext_imm (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
666 const aarch64_insn code
,
667 const aarch64_inst
*inst
,
668 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
672 imm
= extract_all_fields (self
, code
);
674 if (operand_need_sign_extension (self
))
675 imm
= sign_extend (imm
, get_operand_fields_width (self
) - 1);
677 if (operand_need_shift_by_two (self
))
679 else if (operand_need_shift_by_four (self
))
682 if (info
->type
== AARCH64_OPND_ADDR_ADRP
)
685 if (inst
->operands
[0].type
== AARCH64_OPND_PSTATEFIELD
686 && inst
->operands
[0].sysreg
.flags
& F_IMM_IN_CRM
)
687 imm
&= PSTATE_DECODE_CRM_IMM (inst
->operands
[0].sysreg
.flags
);
689 info
->imm
.value
= imm
;
693 /* Decode imm and its shifter for e.g. MOVZ <Wd>, #<imm16>{, LSL #<shift>}. */
695 aarch64_ext_imm_half (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
696 const aarch64_insn code
,
697 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
698 aarch64_operand_error
*errors
)
700 aarch64_ext_imm (self
, info
, code
, inst
, errors
);
701 info
->shifter
.kind
= AARCH64_MOD_LSL
;
702 info
->shifter
.amount
= extract_field (FLD_hw
, code
, 0) << 4;
706 /* Decode cmode and "a:b:c:d:e:f:g:h" for e.g.
707 MOVI <Vd>.<T>, #<imm8> {, LSL #<amount>}. */
709 aarch64_ext_advsimd_imm_modified (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
710 aarch64_opnd_info
*info
,
711 const aarch64_insn code
,
712 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
713 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
716 enum aarch64_opnd_qualifier opnd0_qualifier
= inst
->operands
[0].qualifier
;
717 aarch64_field field
= {0, 0};
719 assert (info
->idx
== 1);
721 if (info
->type
== AARCH64_OPND_SIMD_FPIMM
)
724 /* a:b:c:d:e:f:g:h */
725 imm
= extract_fields (code
, 0, 2, FLD_abc
, FLD_defgh
);
726 if (!info
->imm
.is_fp
&& aarch64_get_qualifier_esize (opnd0_qualifier
) == 8)
728 /* Either MOVI <Dd>, #<imm>
729 or MOVI <Vd>.2D, #<imm>.
730 <imm> is a 64-bit immediate
731 'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh',
732 encoded in "a:b:c:d:e:f:g:h". */
734 unsigned abcdefgh
= imm
;
735 for (imm
= 0ull, i
= 0; i
< 8; i
++)
736 if (((abcdefgh
>> i
) & 0x1) != 0)
737 imm
|= 0xffull
<< (8 * i
);
739 info
->imm
.value
= imm
;
742 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
743 switch (info
->qualifier
)
745 case AARCH64_OPND_QLF_NIL
:
747 info
->shifter
.kind
= AARCH64_MOD_NONE
;
749 case AARCH64_OPND_QLF_LSL
:
751 info
->shifter
.kind
= AARCH64_MOD_LSL
;
752 switch (aarch64_get_qualifier_esize (opnd0_qualifier
))
754 case 4: gen_sub_field (FLD_cmode
, 1, 2, &field
); break; /* per word */
755 case 2: gen_sub_field (FLD_cmode
, 1, 1, &field
); break; /* per half */
756 case 1: gen_sub_field (FLD_cmode
, 1, 0, &field
); break; /* per byte */
757 default: return false;
759 /* 00: 0; 01: 8; 10:16; 11:24. */
760 info
->shifter
.amount
= extract_field_2 (&field
, code
, 0) << 3;
762 case AARCH64_OPND_QLF_MSL
:
764 info
->shifter
.kind
= AARCH64_MOD_MSL
;
765 gen_sub_field (FLD_cmode
, 0, 1, &field
); /* per word */
766 info
->shifter
.amount
= extract_field_2 (&field
, code
, 0) ? 16 : 8;
775 /* Decode an 8-bit floating-point immediate. */
777 aarch64_ext_fpimm (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
778 const aarch64_insn code
,
779 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
780 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
782 info
->imm
.value
= extract_all_fields (self
, code
);
787 /* Decode a 1-bit rotate immediate (#90 or #270). */
789 aarch64_ext_imm_rotate1 (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
790 const aarch64_insn code
,
791 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
792 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
794 uint64_t rot
= extract_field (self
->fields
[0], code
, 0);
796 info
->imm
.value
= rot
* 180 + 90;
800 /* Decode a 2-bit rotate immediate (#0, #90, #180 or #270). */
802 aarch64_ext_imm_rotate2 (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
803 const aarch64_insn code
,
804 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
805 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
807 uint64_t rot
= extract_field (self
->fields
[0], code
, 0);
809 info
->imm
.value
= rot
* 90;
813 /* Decode scale for e.g. SCVTF <Dd>, <Wn>, #<fbits>. */
815 aarch64_ext_fbits (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
816 aarch64_opnd_info
*info
, const aarch64_insn code
,
817 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
818 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
820 info
->imm
.value
= 64- extract_field (FLD_scale
, code
, 0);
824 /* Decode arithmetic immediate for e.g.
825 SUBS <Wd>, <Wn|WSP>, #<imm> {, <shift>}. */
827 aarch64_ext_aimm (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
828 aarch64_opnd_info
*info
, const aarch64_insn code
,
829 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
830 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
834 info
->shifter
.kind
= AARCH64_MOD_LSL
;
836 value
= extract_field (FLD_shift
, code
, 0);
839 info
->shifter
.amount
= value
? 12 : 0;
840 /* imm12 (unsigned) */
841 info
->imm
.value
= extract_field (FLD_imm12
, code
, 0);
846 /* Return true if VALUE is a valid logical immediate encoding, storing the
847 decoded value in *RESULT if so. ESIZE is the number of bytes in the
848 decoded immediate. */
850 decode_limm (uint32_t esize
, aarch64_insn value
, int64_t *result
)
856 /* value is N:immr:imms. */
858 R
= (value
>> 6) & 0x3f;
859 N
= (value
>> 12) & 0x1;
861 /* The immediate value is S+1 bits to 1, left rotated by SIMDsize - R
862 (in other words, right rotated by R), then replicated. */
866 mask
= 0xffffffffffffffffull
;
872 case 0x00 ... 0x1f: /* 0xxxxx */ simd_size
= 32; break;
873 case 0x20 ... 0x2f: /* 10xxxx */ simd_size
= 16; S
&= 0xf; break;
874 case 0x30 ... 0x37: /* 110xxx */ simd_size
= 8; S
&= 0x7; break;
875 case 0x38 ... 0x3b: /* 1110xx */ simd_size
= 4; S
&= 0x3; break;
876 case 0x3c ... 0x3d: /* 11110x */ simd_size
= 2; S
&= 0x1; break;
877 default: return false;
879 mask
= (1ull << simd_size
) - 1;
880 /* Top bits are IGNORED. */
884 if (simd_size
> esize
* 8)
887 /* NOTE: if S = simd_size - 1 we get 0xf..f which is rejected. */
888 if (S
== simd_size
- 1)
890 /* S+1 consecutive bits to 1. */
891 /* NOTE: S can't be 63 due to detection above. */
892 imm
= (1ull << (S
+ 1)) - 1;
893 /* Rotate to the left by simd_size - R. */
895 imm
= ((imm
<< (simd_size
- R
)) & mask
) | (imm
>> R
);
896 /* Replicate the value according to SIMD size. */
899 case 2: imm
= (imm
<< 2) | imm
;
901 case 4: imm
= (imm
<< 4) | imm
;
903 case 8: imm
= (imm
<< 8) | imm
;
905 case 16: imm
= (imm
<< 16) | imm
;
907 case 32: imm
= (imm
<< 32) | imm
;
913 *result
= imm
& ~((uint64_t) -1 << (esize
* 4) << (esize
* 4));
918 /* Decode a logical immediate for e.g. ORR <Wd|WSP>, <Wn>, #<imm>. */
920 aarch64_ext_limm (const aarch64_operand
*self
,
921 aarch64_opnd_info
*info
, const aarch64_insn code
,
922 const aarch64_inst
*inst
,
923 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
928 value
= extract_fields (code
, 0, 3, self
->fields
[0], self
->fields
[1],
930 esize
= aarch64_get_qualifier_esize (inst
->operands
[0].qualifier
);
931 return decode_limm (esize
, value
, &info
->imm
.value
);
934 /* Decode a logical immediate for the BIC alias of AND (etc.). */
936 aarch64_ext_inv_limm (const aarch64_operand
*self
,
937 aarch64_opnd_info
*info
, const aarch64_insn code
,
938 const aarch64_inst
*inst
,
939 aarch64_operand_error
*errors
)
941 if (!aarch64_ext_limm (self
, info
, code
, inst
, errors
))
943 info
->imm
.value
= ~info
->imm
.value
;
947 /* Decode Ft for e.g. STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]
948 or LDP <Qt1>, <Qt2>, [<Xn|SP>], #<imm>. */
950 aarch64_ext_ft (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
951 aarch64_opnd_info
*info
,
952 const aarch64_insn code
, const aarch64_inst
*inst
,
953 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
958 info
->reg
.regno
= extract_field (FLD_Rt
, code
, 0);
961 value
= extract_field (FLD_ldst_size
, code
, 0);
962 if (inst
->opcode
->iclass
== ldstpair_indexed
963 || inst
->opcode
->iclass
== ldstnapair_offs
964 || inst
->opcode
->iclass
== ldstpair_off
965 || inst
->opcode
->iclass
== loadlit
)
967 enum aarch64_opnd_qualifier qualifier
;
970 case 0: qualifier
= AARCH64_OPND_QLF_S_S
; break;
971 case 1: qualifier
= AARCH64_OPND_QLF_S_D
; break;
972 case 2: qualifier
= AARCH64_OPND_QLF_S_Q
; break;
973 default: return false;
975 info
->qualifier
= qualifier
;
980 value
= extract_fields (code
, 0, 2, FLD_opc1
, FLD_ldst_size
);
983 info
->qualifier
= get_sreg_qualifier_from_value (value
);
989 /* Decode the address operand for e.g. STXRB <Ws>, <Wt>, [<Xn|SP>{,#0}]. */
991 aarch64_ext_addr_simple (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
992 aarch64_opnd_info
*info
,
994 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
995 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
998 info
->addr
.base_regno
= extract_field (FLD_Rn
, code
, 0);
1002 /* Decode the address operand for e.g.
1003 stlur <Xt>, [<Xn|SP>{, <amount>}]. */
1005 aarch64_ext_addr_offset (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1006 aarch64_opnd_info
*info
,
1007 aarch64_insn code
, const aarch64_inst
*inst
,
1008 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1010 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
1013 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1016 aarch64_insn imm
= extract_fields (code
, 0, 1, self
->fields
[1]);
1017 info
->addr
.offset
.imm
= sign_extend (imm
, 8);
1018 if (extract_field (self
->fields
[2], code
, 0) == 1) {
1019 info
->addr
.writeback
= 1;
1020 info
->addr
.preind
= 1;
1025 /* Decode the address operand for e.g.
1026 STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]. */
1028 aarch64_ext_addr_regoff (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1029 aarch64_opnd_info
*info
,
1030 aarch64_insn code
, const aarch64_inst
*inst
,
1031 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1033 aarch64_insn S
, value
;
1036 info
->addr
.base_regno
= extract_field (FLD_Rn
, code
, 0);
1038 info
->addr
.offset
.regno
= extract_field (FLD_Rm
, code
, 0);
1040 value
= extract_field (FLD_option
, code
, 0);
1041 info
->shifter
.kind
=
1042 aarch64_get_operand_modifier_from_value (value
, true /* extend_p */);
1043 /* Fix-up the shifter kind; although the table-driven approach is
1044 efficient, it is slightly inflexible, thus needing this fix-up. */
1045 if (info
->shifter
.kind
== AARCH64_MOD_UXTX
)
1046 info
->shifter
.kind
= AARCH64_MOD_LSL
;
1048 S
= extract_field (FLD_S
, code
, 0);
1051 info
->shifter
.amount
= 0;
1052 info
->shifter
.amount_present
= 0;
1057 /* Need information in other operand(s) to help achieve the decoding
1059 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
1060 /* Get the size of the data element that is accessed, which may be
1061 different from that of the source register size, e.g. in strb/ldrb. */
1062 size
= aarch64_get_qualifier_esize (info
->qualifier
);
1063 info
->shifter
.amount
= get_logsz (size
);
1064 info
->shifter
.amount_present
= 1;
1070 /* Decode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>], #<simm>. */
1072 aarch64_ext_addr_simm (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
1073 aarch64_insn code
, const aarch64_inst
*inst
,
1074 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1077 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
1080 info
->addr
.base_regno
= extract_field (FLD_Rn
, code
, 0);
1081 /* simm (imm9 or imm7) */
1082 imm
= extract_field (self
->fields
[0], code
, 0);
1083 info
->addr
.offset
.imm
= sign_extend (imm
, fields
[self
->fields
[0]].width
- 1);
1084 if (self
->fields
[0] == FLD_imm7
1085 || info
->qualifier
== AARCH64_OPND_QLF_imm_tag
)
1086 /* scaled immediate in ld/st pair instructions. */
1087 info
->addr
.offset
.imm
*= aarch64_get_qualifier_esize (info
->qualifier
);
1089 if (inst
->opcode
->iclass
== ldst_unscaled
1090 || inst
->opcode
->iclass
== ldstnapair_offs
1091 || inst
->opcode
->iclass
== ldstpair_off
1092 || inst
->opcode
->iclass
== ldst_unpriv
)
1093 info
->addr
.writeback
= 0;
1096 /* pre/post- index */
1097 info
->addr
.writeback
= 1;
1098 if (extract_field (self
->fields
[1], code
, 0) == 1)
1099 info
->addr
.preind
= 1;
1101 info
->addr
.postind
= 1;
1107 /* Decode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>{, #<simm>}]. */
1109 aarch64_ext_addr_uimm12 (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
1111 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1112 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1115 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
1116 shift
= get_logsz (aarch64_get_qualifier_esize (info
->qualifier
));
1118 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1120 info
->addr
.offset
.imm
= extract_field (self
->fields
[1], code
, 0) << shift
;
1124 /* Decode the address operand for e.g. LDRAA <Xt>, [<Xn|SP>{, #<simm>}]. */
1126 aarch64_ext_addr_simm10 (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
1128 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1129 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1133 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
1135 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1137 imm
= extract_fields (code
, 0, 2, self
->fields
[1], self
->fields
[2]);
1138 info
->addr
.offset
.imm
= sign_extend (imm
, 9) << 3;
1139 if (extract_field (self
->fields
[3], code
, 0) == 1) {
1140 info
->addr
.writeback
= 1;
1141 info
->addr
.preind
= 1;
1146 /* Decode the address operand for e.g.
1147 LD1 {<Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>}, [<Xn|SP>], <Xm|#<amount>>. */
1149 aarch64_ext_simd_addr_post (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1150 aarch64_opnd_info
*info
,
1151 aarch64_insn code
, const aarch64_inst
*inst
,
1152 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1154 /* The opcode dependent area stores the number of elements in
1155 each structure to be loaded/stored. */
1156 int is_ld1r
= get_opcode_dependent_value (inst
->opcode
) == 1;
1159 info
->addr
.base_regno
= extract_field (FLD_Rn
, code
, 0);
1160 /* Rm | #<amount> */
1161 info
->addr
.offset
.regno
= extract_field (FLD_Rm
, code
, 0);
1162 if (info
->addr
.offset
.regno
== 31)
1164 if (inst
->opcode
->operands
[0] == AARCH64_OPND_LVt_AL
)
1165 /* Special handling of loading single structure to all lane. */
1166 info
->addr
.offset
.imm
= (is_ld1r
? 1
1167 : inst
->operands
[0].reglist
.num_regs
)
1168 * aarch64_get_qualifier_esize (inst
->operands
[0].qualifier
);
1170 info
->addr
.offset
.imm
= inst
->operands
[0].reglist
.num_regs
1171 * aarch64_get_qualifier_esize (inst
->operands
[0].qualifier
)
1172 * aarch64_get_qualifier_nelem (inst
->operands
[0].qualifier
);
1175 info
->addr
.offset
.is_reg
= 1;
1176 info
->addr
.writeback
= 1;
1181 /* Decode the condition operand for e.g. CSEL <Xd>, <Xn>, <Xm>, <cond>. */
1183 aarch64_ext_cond (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1184 aarch64_opnd_info
*info
,
1185 aarch64_insn code
, const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1186 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1190 value
= extract_field (FLD_cond
, code
, 0);
1191 info
->cond
= get_cond_from_value (value
);
1195 /* Decode the system register operand for e.g. MRS <Xt>, <systemreg>. */
1197 aarch64_ext_sysreg (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1198 aarch64_opnd_info
*info
,
1200 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1201 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1203 /* op0:op1:CRn:CRm:op2 */
1204 info
->sysreg
.value
= extract_fields (code
, 0, 5, FLD_op0
, FLD_op1
, FLD_CRn
,
1206 info
->sysreg
.flags
= 0;
1208 /* If a system instruction, check which restrictions should be on the register
1209 value during decoding, these will be enforced then. */
1210 if (inst
->opcode
->iclass
== ic_system
)
1212 /* Check to see if it's read-only, else check if it's write only.
1213 if it's both or unspecified don't care. */
1214 if ((inst
->opcode
->flags
& (F_SYS_READ
| F_SYS_WRITE
)) == F_SYS_READ
)
1215 info
->sysreg
.flags
= F_REG_READ
;
1216 else if ((inst
->opcode
->flags
& (F_SYS_READ
| F_SYS_WRITE
))
1218 info
->sysreg
.flags
= F_REG_WRITE
;
1224 /* Decode the PSTATE field operand for e.g. MSR <pstatefield>, #<imm>. */
1226 aarch64_ext_pstatefield (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1227 aarch64_opnd_info
*info
, aarch64_insn code
,
1228 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1229 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1232 aarch64_insn fld_crm
= extract_field (FLD_CRm
, code
, 0);
1234 info
->pstatefield
= extract_fields (code
, 0, 2, FLD_op1
, FLD_op2
);
1235 for (i
= 0; aarch64_pstatefields
[i
].name
!= NULL
; ++i
)
1236 if (aarch64_pstatefields
[i
].value
== (aarch64_insn
)info
->pstatefield
)
1238 /* PSTATEFIELD name can be encoded partially in CRm[3:1]. */
1239 uint32_t flags
= aarch64_pstatefields
[i
].flags
;
1240 if ((flags
& F_REG_IN_CRM
)
1241 && ((fld_crm
& 0xe) != PSTATE_DECODE_CRM (flags
)))
1243 info
->sysreg
.flags
= flags
;
1246 /* Reserved value in <pstatefield>. */
1250 /* Decode the system instruction op operand for e.g. AT <at_op>, <Xt>. */
1252 aarch64_ext_sysins_op (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1253 aarch64_opnd_info
*info
,
1255 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1256 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1260 const aarch64_sys_ins_reg
*sysins_ops
;
1261 /* op0:op1:CRn:CRm:op2 */
1262 value
= extract_fields (code
, 0, 5,
1263 FLD_op0
, FLD_op1
, FLD_CRn
,
1268 case AARCH64_OPND_SYSREG_AT
: sysins_ops
= aarch64_sys_regs_at
; break;
1269 case AARCH64_OPND_SYSREG_DC
: sysins_ops
= aarch64_sys_regs_dc
; break;
1270 case AARCH64_OPND_SYSREG_IC
: sysins_ops
= aarch64_sys_regs_ic
; break;
1271 case AARCH64_OPND_SYSREG_TLBI
: sysins_ops
= aarch64_sys_regs_tlbi
; break;
1272 case AARCH64_OPND_SYSREG_SR
:
1273 sysins_ops
= aarch64_sys_regs_sr
;
1274 /* Let's remove op2 for rctx. Refer to comments in the definition of
1275 aarch64_sys_regs_sr[]. */
1276 value
= value
& ~(0x7);
1278 default: return false;
1281 for (i
= 0; sysins_ops
[i
].name
!= NULL
; ++i
)
1282 if (sysins_ops
[i
].value
== value
)
1284 info
->sysins_op
= sysins_ops
+ i
;
1285 DEBUG_TRACE ("%s found value: %x, has_xt: %d, i: %d.",
1286 info
->sysins_op
->name
,
1287 (unsigned)info
->sysins_op
->value
,
1288 aarch64_sys_ins_reg_has_xt (info
->sysins_op
), i
);
1295 /* Decode the memory barrier option operand for e.g. DMB <option>|#<imm>. */
1298 aarch64_ext_barrier (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1299 aarch64_opnd_info
*info
,
1301 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1302 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1305 info
->barrier
= aarch64_barrier_options
+ extract_field (FLD_CRm
, code
, 0);
1309 /* Decode the memory barrier option operand for DSB <option>nXS|#<imm>. */
1312 aarch64_ext_barrier_dsb_nxs (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1313 aarch64_opnd_info
*info
,
1315 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1316 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1318 /* For the DSB nXS barrier variant immediate is encoded in 2-bit field. */
1319 aarch64_insn field
= extract_field (FLD_CRm_dsb_nxs
, code
, 0);
1320 info
->barrier
= aarch64_barrier_dsb_nxs_options
+ field
;
1324 /* Decode the prefetch operation option operand for e.g.
1325 PRFM <prfop>, [<Xn|SP>{, #<pimm>}]. */
1328 aarch64_ext_prfop (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1329 aarch64_opnd_info
*info
,
1330 aarch64_insn code
, const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1331 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1334 info
->prfop
= aarch64_prfops
+ extract_field (FLD_Rt
, code
, 0);
1338 /* Decode the hint number for an alias taking an operand. Set info->hint_option
1339 to the matching name/value pair in aarch64_hint_options. */
1342 aarch64_ext_hint (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1343 aarch64_opnd_info
*info
,
1345 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1346 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1349 unsigned hint_number
;
1352 hint_number
= extract_fields (code
, 0, 2, FLD_CRm
, FLD_op2
);
1354 for (i
= 0; aarch64_hint_options
[i
].name
!= NULL
; i
++)
1356 if (hint_number
== HINT_VAL (aarch64_hint_options
[i
].value
))
1358 info
->hint_option
= &(aarch64_hint_options
[i
]);
1366 /* Decode the extended register operand for e.g.
1367 STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]. */
1369 aarch64_ext_reg_extended (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1370 aarch64_opnd_info
*info
,
1372 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1373 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1378 info
->reg
.regno
= extract_field (FLD_Rm
, code
, 0);
1380 value
= extract_field (FLD_option
, code
, 0);
1381 info
->shifter
.kind
=
1382 aarch64_get_operand_modifier_from_value (value
, true /* extend_p */);
1384 info
->shifter
.amount
= extract_field (FLD_imm3
, code
, 0);
1386 /* This makes the constraint checking happy. */
1387 info
->shifter
.operator_present
= 1;
1389 /* Assume inst->operands[0].qualifier has been resolved. */
1390 assert (inst
->operands
[0].qualifier
!= AARCH64_OPND_QLF_NIL
);
1391 info
->qualifier
= AARCH64_OPND_QLF_W
;
1392 if (inst
->operands
[0].qualifier
== AARCH64_OPND_QLF_X
1393 && (info
->shifter
.kind
== AARCH64_MOD_UXTX
1394 || info
->shifter
.kind
== AARCH64_MOD_SXTX
))
1395 info
->qualifier
= AARCH64_OPND_QLF_X
;
1400 /* Decode the shifted register operand for e.g.
1401 SUBS <Xd>, <Xn>, <Xm> {, <shift> #<amount>}. */
1403 aarch64_ext_reg_shifted (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1404 aarch64_opnd_info
*info
,
1406 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1407 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1412 info
->reg
.regno
= extract_field (FLD_Rm
, code
, 0);
1414 value
= extract_field (FLD_shift
, code
, 0);
1415 info
->shifter
.kind
=
1416 aarch64_get_operand_modifier_from_value (value
, false /* extend_p */);
1417 if (info
->shifter
.kind
== AARCH64_MOD_ROR
1418 && inst
->opcode
->iclass
!= log_shift
)
1419 /* ROR is not available for the shifted register operand in arithmetic
1423 info
->shifter
.amount
= extract_field (FLD_imm6
, code
, 0);
1425 /* This makes the constraint checking happy. */
1426 info
->shifter
.operator_present
= 1;
1431 /* Decode an SVE address [<base>, #<offset>*<factor>, MUL VL],
1432 where <offset> is given by the OFFSET parameter and where <factor> is
1433 1 plus SELF's operand-dependent value. fields[0] specifies the field
1434 that holds <base>. */
1436 aarch64_ext_sve_addr_reg_mul_vl (const aarch64_operand
*self
,
1437 aarch64_opnd_info
*info
, aarch64_insn code
,
1440 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1441 info
->addr
.offset
.imm
= offset
* (1 + get_operand_specific_data (self
));
1442 info
->addr
.offset
.is_reg
= false;
1443 info
->addr
.writeback
= false;
1444 info
->addr
.preind
= true;
1446 info
->shifter
.kind
= AARCH64_MOD_MUL_VL
;
1447 info
->shifter
.amount
= 1;
1448 info
->shifter
.operator_present
= (info
->addr
.offset
.imm
!= 0);
1449 info
->shifter
.amount_present
= false;
1453 /* Decode an SVE address [<base>, #<simm4>*<factor>, MUL VL],
1454 where <simm4> is a 4-bit signed value and where <factor> is 1 plus
1455 SELF's operand-dependent value. fields[0] specifies the field that
1456 holds <base>. <simm4> is encoded in the SVE_imm4 field. */
1458 aarch64_ext_sve_addr_ri_s4xvl (const aarch64_operand
*self
,
1459 aarch64_opnd_info
*info
, aarch64_insn code
,
1460 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1461 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1465 offset
= extract_field (FLD_SVE_imm4
, code
, 0);
1466 offset
= ((offset
+ 8) & 15) - 8;
1467 return aarch64_ext_sve_addr_reg_mul_vl (self
, info
, code
, offset
);
1470 /* Decode an SVE address [<base>, #<simm6>*<factor>, MUL VL],
1471 where <simm6> is a 6-bit signed value and where <factor> is 1 plus
1472 SELF's operand-dependent value. fields[0] specifies the field that
1473 holds <base>. <simm6> is encoded in the SVE_imm6 field. */
1475 aarch64_ext_sve_addr_ri_s6xvl (const aarch64_operand
*self
,
1476 aarch64_opnd_info
*info
, aarch64_insn code
,
1477 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1478 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1482 offset
= extract_field (FLD_SVE_imm6
, code
, 0);
1483 offset
= (((offset
+ 32) & 63) - 32);
1484 return aarch64_ext_sve_addr_reg_mul_vl (self
, info
, code
, offset
);
1487 /* Decode an SVE address [<base>, #<simm9>*<factor>, MUL VL],
1488 where <simm9> is a 9-bit signed value and where <factor> is 1 plus
1489 SELF's operand-dependent value. fields[0] specifies the field that
1490 holds <base>. <simm9> is encoded in the concatenation of the SVE_imm6
1491 and imm3 fields, with imm3 being the less-significant part. */
1493 aarch64_ext_sve_addr_ri_s9xvl (const aarch64_operand
*self
,
1494 aarch64_opnd_info
*info
,
1496 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1497 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1501 offset
= extract_fields (code
, 0, 2, FLD_SVE_imm6
, FLD_imm3
);
1502 offset
= (((offset
+ 256) & 511) - 256);
1503 return aarch64_ext_sve_addr_reg_mul_vl (self
, info
, code
, offset
);
1506 /* Decode an SVE address [<base>, #<offset> << <shift>], where <offset>
1507 is given by the OFFSET parameter and where <shift> is SELF's operand-
1508 dependent value. fields[0] specifies the base register field <base>. */
1510 aarch64_ext_sve_addr_reg_imm (const aarch64_operand
*self
,
1511 aarch64_opnd_info
*info
, aarch64_insn code
,
1514 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1515 info
->addr
.offset
.imm
= offset
* (1 << get_operand_specific_data (self
));
1516 info
->addr
.offset
.is_reg
= false;
1517 info
->addr
.writeback
= false;
1518 info
->addr
.preind
= true;
1519 info
->shifter
.operator_present
= false;
1520 info
->shifter
.amount_present
= false;
1524 /* Decode an SVE address [X<n>, #<SVE_imm4> << <shift>], where <SVE_imm4>
1525 is a 4-bit signed number and where <shift> is SELF's operand-dependent
1526 value. fields[0] specifies the base register field. */
1528 aarch64_ext_sve_addr_ri_s4 (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
= sign_extend (extract_field (FLD_SVE_imm4
, code
, 0), 3);
1534 return aarch64_ext_sve_addr_reg_imm (self
, info
, code
, offset
);
1537 /* Decode an SVE address [X<n>, #<SVE_imm6> << <shift>], where <SVE_imm6>
1538 is a 6-bit unsigned number and where <shift> is SELF's operand-dependent
1539 value. fields[0] specifies the base register field. */
1541 aarch64_ext_sve_addr_ri_u6 (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
)
1546 int offset
= extract_field (FLD_SVE_imm6
, code
, 0);
1547 return aarch64_ext_sve_addr_reg_imm (self
, info
, code
, offset
);
1550 /* Decode an SVE address [X<n>, X<m>{, LSL #<shift>}], where <shift>
1551 is SELF's operand-dependent value. fields[0] specifies the base
1552 register field and fields[1] specifies the offset register field. */
1554 aarch64_ext_sve_addr_rr_lsl (const aarch64_operand
*self
,
1555 aarch64_opnd_info
*info
, aarch64_insn code
,
1556 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1557 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1561 index_regno
= extract_field (self
->fields
[1], code
, 0);
1562 if (index_regno
== 31 && (self
->flags
& OPD_F_NO_ZR
) != 0)
1565 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1566 info
->addr
.offset
.regno
= index_regno
;
1567 info
->addr
.offset
.is_reg
= true;
1568 info
->addr
.writeback
= false;
1569 info
->addr
.preind
= true;
1570 info
->shifter
.kind
= AARCH64_MOD_LSL
;
1571 info
->shifter
.amount
= get_operand_specific_data (self
);
1572 info
->shifter
.operator_present
= (info
->shifter
.amount
!= 0);
1573 info
->shifter
.amount_present
= (info
->shifter
.amount
!= 0);
1577 /* Decode an SVE address [X<n>, Z<m>.<T>, (S|U)XTW {#<shift>}], where
1578 <shift> is SELF's operand-dependent value. fields[0] specifies the
1579 base register field, fields[1] specifies the offset register field and
1580 fields[2] is a single-bit field that selects SXTW over UXTW. */
1582 aarch64_ext_sve_addr_rz_xtw (const aarch64_operand
*self
,
1583 aarch64_opnd_info
*info
, aarch64_insn code
,
1584 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1585 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1587 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1588 info
->addr
.offset
.regno
= extract_field (self
->fields
[1], code
, 0);
1589 info
->addr
.offset
.is_reg
= true;
1590 info
->addr
.writeback
= false;
1591 info
->addr
.preind
= true;
1592 if (extract_field (self
->fields
[2], code
, 0))
1593 info
->shifter
.kind
= AARCH64_MOD_SXTW
;
1595 info
->shifter
.kind
= AARCH64_MOD_UXTW
;
1596 info
->shifter
.amount
= get_operand_specific_data (self
);
1597 info
->shifter
.operator_present
= true;
1598 info
->shifter
.amount_present
= (info
->shifter
.amount
!= 0);
1602 /* Decode an SVE address [Z<n>.<T>, #<imm5> << <shift>], where <imm5> is a
1603 5-bit unsigned number and where <shift> is SELF's operand-dependent value.
1604 fields[0] specifies the base register field. */
1606 aarch64_ext_sve_addr_zi_u5 (const aarch64_operand
*self
,
1607 aarch64_opnd_info
*info
, aarch64_insn code
,
1608 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1609 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1611 int offset
= extract_field (FLD_imm5
, code
, 0);
1612 return aarch64_ext_sve_addr_reg_imm (self
, info
, code
, offset
);
1615 /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>{, <modifier> {#<msz>}}],
1616 where <modifier> is given by KIND and where <msz> is a 2-bit unsigned
1617 number. fields[0] specifies the base register field and fields[1]
1618 specifies the offset register field. */
1620 aarch64_ext_sve_addr_zz (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
1621 aarch64_insn code
, enum aarch64_modifier_kind kind
)
1623 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1624 info
->addr
.offset
.regno
= extract_field (self
->fields
[1], code
, 0);
1625 info
->addr
.offset
.is_reg
= true;
1626 info
->addr
.writeback
= false;
1627 info
->addr
.preind
= true;
1628 info
->shifter
.kind
= kind
;
1629 info
->shifter
.amount
= extract_field (FLD_SVE_msz
, code
, 0);
1630 info
->shifter
.operator_present
= (kind
!= AARCH64_MOD_LSL
1631 || info
->shifter
.amount
!= 0);
1632 info
->shifter
.amount_present
= (info
->shifter
.amount
!= 0);
1636 /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>{, LSL #<msz>}], where
1637 <msz> is a 2-bit unsigned number. fields[0] specifies the base register
1638 field and fields[1] specifies the offset register field. */
1640 aarch64_ext_sve_addr_zz_lsl (const aarch64_operand
*self
,
1641 aarch64_opnd_info
*info
, aarch64_insn code
,
1642 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1643 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1645 return aarch64_ext_sve_addr_zz (self
, info
, code
, AARCH64_MOD_LSL
);
1648 /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>, SXTW {#<msz>}], where
1649 <msz> is a 2-bit unsigned number. fields[0] specifies the base register
1650 field and fields[1] specifies the offset register field. */
1652 aarch64_ext_sve_addr_zz_sxtw (const aarch64_operand
*self
,
1653 aarch64_opnd_info
*info
, aarch64_insn code
,
1654 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1655 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1657 return aarch64_ext_sve_addr_zz (self
, info
, code
, AARCH64_MOD_SXTW
);
1660 /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>, UXTW {#<msz>}], where
1661 <msz> is a 2-bit unsigned number. fields[0] specifies the base register
1662 field and fields[1] specifies the offset register field. */
1664 aarch64_ext_sve_addr_zz_uxtw (const aarch64_operand
*self
,
1665 aarch64_opnd_info
*info
, aarch64_insn code
,
1666 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1667 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1669 return aarch64_ext_sve_addr_zz (self
, info
, code
, AARCH64_MOD_UXTW
);
1672 /* Finish decoding an SVE arithmetic immediate, given that INFO already
1673 has the raw field value and that the low 8 bits decode to VALUE. */
1675 decode_sve_aimm (aarch64_opnd_info
*info
, int64_t value
)
1677 info
->shifter
.kind
= AARCH64_MOD_LSL
;
1678 info
->shifter
.amount
= 0;
1679 if (info
->imm
.value
& 0x100)
1682 /* Decode 0x100 as #0, LSL #8. */
1683 info
->shifter
.amount
= 8;
1687 info
->shifter
.operator_present
= (info
->shifter
.amount
!= 0);
1688 info
->shifter
.amount_present
= (info
->shifter
.amount
!= 0);
1689 info
->imm
.value
= value
;
1693 /* Decode an SVE ADD/SUB immediate. */
1695 aarch64_ext_sve_aimm (const aarch64_operand
*self
,
1696 aarch64_opnd_info
*info
, const aarch64_insn code
,
1697 const aarch64_inst
*inst
,
1698 aarch64_operand_error
*errors
)
1700 return (aarch64_ext_imm (self
, info
, code
, inst
, errors
)
1701 && decode_sve_aimm (info
, (uint8_t) info
->imm
.value
));
1704 /* Decode an SVE CPY/DUP immediate. */
1706 aarch64_ext_sve_asimm (const aarch64_operand
*self
,
1707 aarch64_opnd_info
*info
, const aarch64_insn code
,
1708 const aarch64_inst
*inst
,
1709 aarch64_operand_error
*errors
)
1711 return (aarch64_ext_imm (self
, info
, code
, inst
, errors
)
1712 && decode_sve_aimm (info
, (int8_t) info
->imm
.value
));
1715 /* Decode a single-bit immediate that selects between #0.5 and #1.0.
1716 The fields array specifies which field to use. */
1718 aarch64_ext_sve_float_half_one (const aarch64_operand
*self
,
1719 aarch64_opnd_info
*info
, aarch64_insn code
,
1720 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1721 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1723 if (extract_field (self
->fields
[0], code
, 0))
1724 info
->imm
.value
= 0x3f800000;
1726 info
->imm
.value
= 0x3f000000;
1727 info
->imm
.is_fp
= true;
1731 /* Decode a single-bit immediate that selects between #0.5 and #2.0.
1732 The fields array specifies which field to use. */
1734 aarch64_ext_sve_float_half_two (const aarch64_operand
*self
,
1735 aarch64_opnd_info
*info
, aarch64_insn code
,
1736 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1737 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1739 if (extract_field (self
->fields
[0], code
, 0))
1740 info
->imm
.value
= 0x40000000;
1742 info
->imm
.value
= 0x3f000000;
1743 info
->imm
.is_fp
= true;
1747 /* Decode a single-bit immediate that selects between #0.0 and #1.0.
1748 The fields array specifies which field to use. */
1750 aarch64_ext_sve_float_zero_one (const aarch64_operand
*self
,
1751 aarch64_opnd_info
*info
, aarch64_insn code
,
1752 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1753 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1755 if (extract_field (self
->fields
[0], code
, 0))
1756 info
->imm
.value
= 0x3f800000;
1758 info
->imm
.value
= 0x0;
1759 info
->imm
.is_fp
= true;
1763 /* Decode ZA tile vector, vector indicator, vector selector, qualifier and
1764 immediate on numerous SME instruction fields such as MOVA. */
1766 aarch64_ext_sme_za_hv_tiles (const aarch64_operand
*self
,
1767 aarch64_opnd_info
*info
, aarch64_insn code
,
1768 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1769 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1771 int fld_size
= extract_field (self
->fields
[0], code
, 0);
1772 int fld_q
= extract_field (self
->fields
[1], code
, 0);
1773 int fld_v
= extract_field (self
->fields
[2], code
, 0);
1774 int fld_rv
= extract_field (self
->fields
[3], code
, 0);
1775 int fld_zan_imm
= extract_field (self
->fields
[4], code
, 0);
1777 /* Deduce qualifier encoded in size and Q fields. */
1779 info
->qualifier
= AARCH64_OPND_QLF_S_B
;
1780 else if (fld_size
== 1)
1781 info
->qualifier
= AARCH64_OPND_QLF_S_H
;
1782 else if (fld_size
== 2)
1783 info
->qualifier
= AARCH64_OPND_QLF_S_S
;
1784 else if (fld_size
== 3 && fld_q
== 0)
1785 info
->qualifier
= AARCH64_OPND_QLF_S_D
;
1786 else if (fld_size
== 3 && fld_q
== 1)
1787 info
->qualifier
= AARCH64_OPND_QLF_S_Q
;
1789 info
->za_tile_vector
.index
.regno
= fld_rv
+ 12;
1790 info
->za_tile_vector
.v
= fld_v
;
1792 switch (info
->qualifier
)
1794 case AARCH64_OPND_QLF_S_B
:
1795 info
->za_tile_vector
.regno
= 0;
1796 info
->za_tile_vector
.index
.imm
= fld_zan_imm
;
1798 case AARCH64_OPND_QLF_S_H
:
1799 info
->za_tile_vector
.regno
= fld_zan_imm
>> 3;
1800 info
->za_tile_vector
.index
.imm
= fld_zan_imm
& 0x07;
1802 case AARCH64_OPND_QLF_S_S
:
1803 info
->za_tile_vector
.regno
= fld_zan_imm
>> 2;
1804 info
->za_tile_vector
.index
.imm
= fld_zan_imm
& 0x03;
1806 case AARCH64_OPND_QLF_S_D
:
1807 info
->za_tile_vector
.regno
= fld_zan_imm
>> 1;
1808 info
->za_tile_vector
.index
.imm
= fld_zan_imm
& 0x01;
1810 case AARCH64_OPND_QLF_S_Q
:
1811 info
->za_tile_vector
.regno
= fld_zan_imm
;
1812 info
->za_tile_vector
.index
.imm
= 0;
1821 /* Decode in SME instruction ZERO list of up to eight 64-bit element tile names
1822 separated by commas, encoded in the "imm8" field.
1824 For programmer convenience an assembler must also accept the names of
1825 32-bit, 16-bit and 8-bit element tiles which are converted into the
1826 corresponding set of 64-bit element tiles.
1829 aarch64_ext_sme_za_list (const aarch64_operand
*self
,
1830 aarch64_opnd_info
*info
, aarch64_insn code
,
1831 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1832 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1834 int mask
= extract_field (self
->fields
[0], code
, 0);
1835 info
->imm
.value
= mask
;
1839 /* Decode ZA array vector select register (Rv field), optional vector and
1840 memory offset (imm4 field).
1843 aarch64_ext_sme_za_array (const aarch64_operand
*self
,
1844 aarch64_opnd_info
*info
, aarch64_insn code
,
1845 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1846 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1848 int regno
= extract_field (self
->fields
[0], code
, 0) + 12;
1849 int imm
= extract_field (self
->fields
[1], code
, 0);
1850 info
->za_tile_vector
.index
.regno
= regno
;
1851 info
->za_tile_vector
.index
.imm
= imm
;
1856 aarch64_ext_sme_addr_ri_u4xvl (const aarch64_operand
*self
,
1857 aarch64_opnd_info
*info
, aarch64_insn code
,
1858 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1859 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1861 int regno
= extract_field (self
->fields
[0], code
, 0);
1862 int imm
= extract_field (self
->fields
[1], code
, 0);
1863 info
->addr
.base_regno
= regno
;
1864 info
->addr
.offset
.imm
= imm
;
1865 /* MUL VL operator is always present for this operand. */
1866 info
->shifter
.kind
= AARCH64_MOD_MUL_VL
;
1867 info
->shifter
.operator_present
= (imm
!= 0);
1871 /* Decode {SM|ZA} filed for SMSTART and SMSTOP instructions. */
1873 aarch64_ext_sme_sm_za (const aarch64_operand
*self
,
1874 aarch64_opnd_info
*info
, aarch64_insn code
,
1875 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1876 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1878 info
->pstatefield
= 0x1b;
1879 aarch64_insn fld_crm
= extract_field (self
->fields
[0], code
, 0);
1880 fld_crm
>>= 1; /* CRm[3:1]. */
1883 info
->reg
.regno
= 's';
1884 else if (fld_crm
== 0x2)
1885 info
->reg
.regno
= 'z';
1893 aarch64_ext_sme_pred_reg_with_index (const aarch64_operand
*self
,
1894 aarch64_opnd_info
*info
, aarch64_insn code
,
1895 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1896 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1898 aarch64_insn fld_rm
= extract_field (self
->fields
[0], code
, 0);
1899 aarch64_insn fld_pn
= extract_field (self
->fields
[1], code
, 0);
1900 aarch64_insn fld_i1
= extract_field (self
->fields
[2], code
, 0);
1901 aarch64_insn fld_tszh
= extract_field (self
->fields
[3], code
, 0);
1902 aarch64_insn fld_tszl
= extract_field (self
->fields
[4], code
, 0);
1905 info
->za_tile_vector
.regno
= fld_pn
;
1906 info
->za_tile_vector
.index
.regno
= fld_rm
+ 12;
1908 if (fld_tszh
== 0x1 && fld_tszl
== 0x0)
1910 info
->qualifier
= AARCH64_OPND_QLF_S_D
;
1913 else if (fld_tszl
== 0x4)
1915 info
->qualifier
= AARCH64_OPND_QLF_S_S
;
1916 imm
= (fld_i1
<< 1) | fld_tszh
;
1918 else if ((fld_tszl
& 0x3) == 0x2)
1920 info
->qualifier
= AARCH64_OPND_QLF_S_H
;
1921 imm
= (fld_i1
<< 2) | (fld_tszh
<< 1) | (fld_tszl
>> 2);
1923 else if (fld_tszl
& 0x1)
1925 info
->qualifier
= AARCH64_OPND_QLF_S_B
;
1926 imm
= (fld_i1
<< 3) | (fld_tszh
<< 2) | (fld_tszl
>> 1);
1931 info
->za_tile_vector
.index
.imm
= imm
;
1935 /* Decode Zn[MM], where MM has a 7-bit triangular encoding. The fields
1936 array specifies which field to use for Zn. MM is encoded in the
1937 concatenation of imm5 and SVE_tszh, with imm5 being the less
1938 significant part. */
1940 aarch64_ext_sve_index (const aarch64_operand
*self
,
1941 aarch64_opnd_info
*info
, aarch64_insn code
,
1942 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1943 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1947 info
->reglane
.regno
= extract_field (self
->fields
[0], code
, 0);
1948 val
= extract_fields (code
, 0, 2, FLD_SVE_tszh
, FLD_imm5
);
1949 if ((val
& 31) == 0)
1951 while ((val
& 1) == 0)
1953 info
->reglane
.index
= val
/ 2;
1957 /* Decode a logical immediate for the MOV alias of SVE DUPM. */
1959 aarch64_ext_sve_limm_mov (const aarch64_operand
*self
,
1960 aarch64_opnd_info
*info
, const aarch64_insn code
,
1961 const aarch64_inst
*inst
,
1962 aarch64_operand_error
*errors
)
1964 int esize
= aarch64_get_qualifier_esize (inst
->operands
[0].qualifier
);
1965 return (aarch64_ext_limm (self
, info
, code
, inst
, errors
)
1966 && aarch64_sve_dupm_mov_immediate_p (info
->imm
.value
, esize
));
1969 /* Decode Zn[MM], where Zn occupies the least-significant part of the field
1970 and where MM occupies the most-significant part. The operand-dependent
1971 value specifies the number of bits in Zn. */
1973 aarch64_ext_sve_quad_index (const aarch64_operand
*self
,
1974 aarch64_opnd_info
*info
, aarch64_insn code
,
1975 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1976 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1978 unsigned int reg_bits
= get_operand_specific_data (self
);
1979 unsigned int val
= extract_all_fields (self
, code
);
1980 info
->reglane
.regno
= val
& ((1 << reg_bits
) - 1);
1981 info
->reglane
.index
= val
>> reg_bits
;
1985 /* Decode {Zn.<T> - Zm.<T>}. The fields array specifies which field
1986 to use for Zn. The opcode-dependent value specifies the number
1987 of registers in the list. */
1989 aarch64_ext_sve_reglist (const aarch64_operand
*self
,
1990 aarch64_opnd_info
*info
, aarch64_insn code
,
1991 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1992 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1994 info
->reglist
.first_regno
= extract_field (self
->fields
[0], code
, 0);
1995 info
->reglist
.num_regs
= get_opcode_dependent_value (inst
->opcode
);
1999 /* Decode <pattern>{, MUL #<amount>}. The fields array specifies which
2000 fields to use for <pattern>. <amount> - 1 is encoded in the SVE_imm4
2003 aarch64_ext_sve_scale (const aarch64_operand
*self
,
2004 aarch64_opnd_info
*info
, aarch64_insn code
,
2005 const aarch64_inst
*inst
, aarch64_operand_error
*errors
)
2009 if (!aarch64_ext_imm (self
, info
, code
, inst
, errors
))
2011 val
= extract_field (FLD_SVE_imm4
, code
, 0);
2012 info
->shifter
.kind
= AARCH64_MOD_MUL
;
2013 info
->shifter
.amount
= val
+ 1;
2014 info
->shifter
.operator_present
= (val
!= 0);
2015 info
->shifter
.amount_present
= (val
!= 0);
2019 /* Return the top set bit in VALUE, which is expected to be relatively
2022 get_top_bit (uint64_t value
)
2024 while ((value
& -value
) != value
)
2025 value
-= value
& -value
;
2029 /* Decode an SVE shift-left immediate. */
2031 aarch64_ext_sve_shlimm (const aarch64_operand
*self
,
2032 aarch64_opnd_info
*info
, const aarch64_insn code
,
2033 const aarch64_inst
*inst
, aarch64_operand_error
*errors
)
2035 if (!aarch64_ext_imm (self
, info
, code
, inst
, errors
)
2036 || info
->imm
.value
== 0)
2039 info
->imm
.value
-= get_top_bit (info
->imm
.value
);
2043 /* Decode an SVE shift-right immediate. */
2045 aarch64_ext_sve_shrimm (const aarch64_operand
*self
,
2046 aarch64_opnd_info
*info
, const aarch64_insn code
,
2047 const aarch64_inst
*inst
, aarch64_operand_error
*errors
)
2049 if (!aarch64_ext_imm (self
, info
, code
, inst
, errors
)
2050 || info
->imm
.value
== 0)
2053 info
->imm
.value
= get_top_bit (info
->imm
.value
) * 2 - info
->imm
.value
;
2057 /* Decode X0-X30. Register 31 is unallocated. */
2059 aarch64_ext_x0_to_x30 (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
2060 const aarch64_insn code
,
2061 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
2062 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
2064 info
->reg
.regno
= extract_field (self
->fields
[0], code
, 0);
2065 return info
->reg
.regno
<= 30;
2068 /* Bitfields that are commonly used to encode certain operands' information
2069 may be partially used as part of the base opcode in some instructions.
2070 For example, the bit 1 of the field 'size' in
2071 FCVTXN <Vb><d>, <Va><n>
2072 is actually part of the base opcode, while only size<0> is available
2073 for encoding the register type. Another example is the AdvSIMD
2074 instruction ORR (register), in which the field 'size' is also used for
2075 the base opcode, leaving only the field 'Q' available to encode the
2076 vector register arrangement specifier '8B' or '16B'.
2078 This function tries to deduce the qualifier from the value of partially
2079 constrained field(s). Given the VALUE of such a field or fields, the
2080 qualifiers CANDIDATES and the MASK (indicating which bits are valid for
2081 operand encoding), the function returns the matching qualifier or
2082 AARCH64_OPND_QLF_NIL if nothing matches.
2084 N.B. CANDIDATES is a group of possible qualifiers that are valid for
2085 one operand; it has a maximum of AARCH64_MAX_QLF_SEQ_NUM qualifiers and
2086 may end with AARCH64_OPND_QLF_NIL. */
2088 static enum aarch64_opnd_qualifier
2089 get_qualifier_from_partial_encoding (aarch64_insn value
,
2090 const enum aarch64_opnd_qualifier
* \
2095 DEBUG_TRACE ("enter with value: %d, mask: %d", (int)value
, (int)mask
);
2096 for (i
= 0; i
< AARCH64_MAX_QLF_SEQ_NUM
; ++i
)
2098 aarch64_insn standard_value
;
2099 if (candidates
[i
] == AARCH64_OPND_QLF_NIL
)
2101 standard_value
= aarch64_get_qualifier_standard_value (candidates
[i
]);
2102 if ((standard_value
& mask
) == (value
& mask
))
2103 return candidates
[i
];
2105 return AARCH64_OPND_QLF_NIL
;
2108 /* Given a list of qualifier sequences, return all possible valid qualifiers
2109 for operand IDX in QUALIFIERS.
2110 Assume QUALIFIERS is an array whose length is large enough. */
2113 get_operand_possible_qualifiers (int idx
,
2114 const aarch64_opnd_qualifier_seq_t
*list
,
2115 enum aarch64_opnd_qualifier
*qualifiers
)
2118 for (i
= 0; i
< AARCH64_MAX_QLF_SEQ_NUM
; ++i
)
2119 if ((qualifiers
[i
] = list
[i
][idx
]) == AARCH64_OPND_QLF_NIL
)
2123 /* Decode the size Q field for e.g. SHADD.
2124 We tag one operand with the qualifer according to the code;
2125 whether the qualifier is valid for this opcode or not, it is the
2126 duty of the semantic checking. */
2129 decode_sizeq (aarch64_inst
*inst
)
2132 enum aarch64_opnd_qualifier qualifier
;
2134 aarch64_insn value
, mask
;
2135 enum aarch64_field_kind fld_sz
;
2136 enum aarch64_opnd_qualifier candidates
[AARCH64_MAX_QLF_SEQ_NUM
];
2138 if (inst
->opcode
->iclass
== asisdlse
2139 || inst
->opcode
->iclass
== asisdlsep
2140 || inst
->opcode
->iclass
== asisdlso
2141 || inst
->opcode
->iclass
== asisdlsop
)
2142 fld_sz
= FLD_vldst_size
;
2147 value
= extract_fields (code
, inst
->opcode
->mask
, 2, fld_sz
, FLD_Q
);
2148 /* Obtain the info that which bits of fields Q and size are actually
2149 available for operand encoding. Opcodes like FMAXNM and FMLA have
2150 size[1] unavailable. */
2151 mask
= extract_fields (~inst
->opcode
->mask
, 0, 2, fld_sz
, FLD_Q
);
2153 /* The index of the operand we are going to tag a qualifier and the qualifer
2154 itself are reasoned from the value of the size and Q fields and the
2155 possible valid qualifier lists. */
2156 idx
= aarch64_select_operand_for_sizeq_field_coding (inst
->opcode
);
2157 DEBUG_TRACE ("key idx: %d", idx
);
2159 /* For most related instruciton, size:Q are fully available for operand
2163 inst
->operands
[idx
].qualifier
= get_vreg_qualifier_from_value (value
);
2167 get_operand_possible_qualifiers (idx
, inst
->opcode
->qualifiers_list
,
2169 #ifdef DEBUG_AARCH64
2173 for (i
= 0; candidates
[i
] != AARCH64_OPND_QLF_NIL
2174 && i
< AARCH64_MAX_QLF_SEQ_NUM
; ++i
)
2175 DEBUG_TRACE ("qualifier %d: %s", i
,
2176 aarch64_get_qualifier_name(candidates
[i
]));
2177 DEBUG_TRACE ("%d, %d", (int)value
, (int)mask
);
2179 #endif /* DEBUG_AARCH64 */
2181 qualifier
= get_qualifier_from_partial_encoding (value
, candidates
, mask
);
2183 if (qualifier
== AARCH64_OPND_QLF_NIL
)
2186 inst
->operands
[idx
].qualifier
= qualifier
;
2190 /* Decode size[0]:Q, i.e. bit 22 and bit 30, for
2191 e.g. FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>. */
2194 decode_asimd_fcvt (aarch64_inst
*inst
)
2196 aarch64_field field
= {0, 0};
2198 enum aarch64_opnd_qualifier qualifier
;
2200 gen_sub_field (FLD_size
, 0, 1, &field
);
2201 value
= extract_field_2 (&field
, inst
->value
, 0);
2202 qualifier
= value
== 0 ? AARCH64_OPND_QLF_V_4S
2203 : AARCH64_OPND_QLF_V_2D
;
2204 switch (inst
->opcode
->op
)
2208 /* FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>. */
2209 inst
->operands
[1].qualifier
= qualifier
;
2213 /* FCVTL<Q> <Vd>.<Ta>, <Vn>.<Tb>. */
2214 inst
->operands
[0].qualifier
= qualifier
;
2223 /* Decode size[0], i.e. bit 22, for
2224 e.g. FCVTXN <Vb><d>, <Va><n>. */
2227 decode_asisd_fcvtxn (aarch64_inst
*inst
)
2229 aarch64_field field
= {0, 0};
2230 gen_sub_field (FLD_size
, 0, 1, &field
);
2231 if (!extract_field_2 (&field
, inst
->value
, 0))
2233 inst
->operands
[0].qualifier
= AARCH64_OPND_QLF_S_S
;
2237 /* Decode the 'opc' field for e.g. FCVT <Dd>, <Sn>. */
2239 decode_fcvt (aarch64_inst
*inst
)
2241 enum aarch64_opnd_qualifier qualifier
;
2243 const aarch64_field field
= {15, 2};
2246 value
= extract_field_2 (&field
, inst
->value
, 0);
2249 case 0: qualifier
= AARCH64_OPND_QLF_S_S
; break;
2250 case 1: qualifier
= AARCH64_OPND_QLF_S_D
; break;
2251 case 3: qualifier
= AARCH64_OPND_QLF_S_H
; break;
2254 inst
->operands
[0].qualifier
= qualifier
;
2259 /* Do miscellaneous decodings that are not common enough to be driven by
2263 do_misc_decoding (aarch64_inst
*inst
)
2266 switch (inst
->opcode
->op
)
2269 return decode_fcvt (inst
);
2275 return decode_asimd_fcvt (inst
);
2278 return decode_asisd_fcvtxn (inst
);
2282 value
= extract_field (FLD_SVE_Pn
, inst
->value
, 0);
2283 return (value
== extract_field (FLD_SVE_Pm
, inst
->value
, 0)
2284 && value
== extract_field (FLD_SVE_Pg4_10
, inst
->value
, 0));
2287 return (extract_field (FLD_SVE_Zd
, inst
->value
, 0)
2288 == extract_field (FLD_SVE_Zm_16
, inst
->value
, 0));
2291 /* Index must be zero. */
2292 value
= extract_fields (inst
->value
, 0, 2, FLD_SVE_tszh
, FLD_imm5
);
2293 return value
> 0 && value
<= 16 && value
== (value
& -value
);
2296 return (extract_field (FLD_SVE_Zn
, inst
->value
, 0)
2297 == extract_field (FLD_SVE_Zm_16
, inst
->value
, 0));
2300 /* Index must be nonzero. */
2301 value
= extract_fields (inst
->value
, 0, 2, FLD_SVE_tszh
, FLD_imm5
);
2302 return value
> 0 && value
!= (value
& -value
);
2305 return (extract_field (FLD_SVE_Pd
, inst
->value
, 0)
2306 == extract_field (FLD_SVE_Pm
, inst
->value
, 0));
2308 case OP_MOVZS_P_P_P
:
2310 return (extract_field (FLD_SVE_Pn
, inst
->value
, 0)
2311 == extract_field (FLD_SVE_Pm
, inst
->value
, 0));
2313 case OP_NOTS_P_P_P_Z
:
2314 case OP_NOT_P_P_P_Z
:
2315 return (extract_field (FLD_SVE_Pm
, inst
->value
, 0)
2316 == extract_field (FLD_SVE_Pg4_10
, inst
->value
, 0));
2323 /* Opcodes that have fields shared by multiple operands are usually flagged
2324 with flags. In this function, we detect such flags, decode the related
2325 field(s) and store the information in one of the related operands. The
2326 'one' operand is not any operand but one of the operands that can
2327 accommadate all the information that has been decoded. */
2330 do_special_decoding (aarch64_inst
*inst
)
2334 /* Condition for truly conditional executed instructions, e.g. b.cond. */
2335 if (inst
->opcode
->flags
& F_COND
)
2337 value
= extract_field (FLD_cond2
, inst
->value
, 0);
2338 inst
->cond
= get_cond_from_value (value
);
2341 if (inst
->opcode
->flags
& F_SF
)
2343 idx
= select_operand_for_sf_field_coding (inst
->opcode
);
2344 value
= extract_field (FLD_sf
, inst
->value
, 0);
2345 inst
->operands
[idx
].qualifier
= get_greg_qualifier_from_value (value
);
2346 if ((inst
->opcode
->flags
& F_N
)
2347 && extract_field (FLD_N
, inst
->value
, 0) != value
)
2351 if (inst
->opcode
->flags
& F_LSE_SZ
)
2353 idx
= select_operand_for_sf_field_coding (inst
->opcode
);
2354 value
= extract_field (FLD_lse_sz
, inst
->value
, 0);
2355 inst
->operands
[idx
].qualifier
= get_greg_qualifier_from_value (value
);
2357 /* size:Q fields. */
2358 if (inst
->opcode
->flags
& F_SIZEQ
)
2359 return decode_sizeq (inst
);
2361 if (inst
->opcode
->flags
& F_FPTYPE
)
2363 idx
= select_operand_for_fptype_field_coding (inst
->opcode
);
2364 value
= extract_field (FLD_type
, inst
->value
, 0);
2367 case 0: inst
->operands
[idx
].qualifier
= AARCH64_OPND_QLF_S_S
; break;
2368 case 1: inst
->operands
[idx
].qualifier
= AARCH64_OPND_QLF_S_D
; break;
2369 case 3: inst
->operands
[idx
].qualifier
= AARCH64_OPND_QLF_S_H
; break;
2374 if (inst
->opcode
->flags
& F_SSIZE
)
2376 /* N.B. some opcodes like FCMGT <V><d>, <V><n>, #0 have the size[1] as part
2377 of the base opcode. */
2379 enum aarch64_opnd_qualifier candidates
[AARCH64_MAX_QLF_SEQ_NUM
];
2380 idx
= select_operand_for_scalar_size_field_coding (inst
->opcode
);
2381 value
= extract_field (FLD_size
, inst
->value
, inst
->opcode
->mask
);
2382 mask
= extract_field (FLD_size
, ~inst
->opcode
->mask
, 0);
2383 /* For most related instruciton, the 'size' field is fully available for
2384 operand encoding. */
2386 inst
->operands
[idx
].qualifier
= get_sreg_qualifier_from_value (value
);
2389 get_operand_possible_qualifiers (idx
, inst
->opcode
->qualifiers_list
,
2391 inst
->operands
[idx
].qualifier
2392 = get_qualifier_from_partial_encoding (value
, candidates
, mask
);
2396 if (inst
->opcode
->flags
& F_T
)
2398 /* Num of consecutive '0's on the right side of imm5<3:0>. */
2401 assert (aarch64_get_operand_class (inst
->opcode
->operands
[0])
2402 == AARCH64_OPND_CLASS_SIMD_REG
);
2413 val
= extract_field (FLD_imm5
, inst
->value
, 0);
2414 while ((val
& 0x1) == 0 && ++num
<= 3)
2418 Q
= (unsigned) extract_field (FLD_Q
, inst
->value
, inst
->opcode
->mask
);
2419 inst
->operands
[0].qualifier
=
2420 get_vreg_qualifier_from_value ((num
<< 1) | Q
);
2423 if (inst
->opcode
->flags
& F_GPRSIZE_IN_Q
)
2425 /* Use Rt to encode in the case of e.g.
2426 STXP <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}]. */
2427 idx
= aarch64_operand_index (inst
->opcode
->operands
, AARCH64_OPND_Rt
);
2430 /* Otherwise use the result operand, which has to be a integer
2432 assert (aarch64_get_operand_class (inst
->opcode
->operands
[0])
2433 == AARCH64_OPND_CLASS_INT_REG
);
2436 assert (idx
== 0 || idx
== 1);
2437 value
= extract_field (FLD_Q
, inst
->value
, 0);
2438 inst
->operands
[idx
].qualifier
= get_greg_qualifier_from_value (value
);
2441 if (inst
->opcode
->flags
& F_LDS_SIZE
)
2443 aarch64_field field
= {0, 0};
2444 assert (aarch64_get_operand_class (inst
->opcode
->operands
[0])
2445 == AARCH64_OPND_CLASS_INT_REG
);
2446 gen_sub_field (FLD_opc
, 0, 1, &field
);
2447 value
= extract_field_2 (&field
, inst
->value
, 0);
2448 inst
->operands
[0].qualifier
2449 = value
? AARCH64_OPND_QLF_W
: AARCH64_OPND_QLF_X
;
2452 /* Miscellaneous decoding; done as the last step. */
2453 if (inst
->opcode
->flags
& F_MISC
)
2454 return do_misc_decoding (inst
);
2459 /* Converters converting a real opcode instruction to its alias form. */
2461 /* ROR <Wd>, <Ws>, #<shift>
2463 EXTR <Wd>, <Ws>, <Ws>, #<shift>. */
2465 convert_extr_to_ror (aarch64_inst
*inst
)
2467 if (inst
->operands
[1].reg
.regno
== inst
->operands
[2].reg
.regno
)
2469 copy_operand_info (inst
, 2, 3);
2470 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
2476 /* UXTL<Q> <Vd>.<Ta>, <Vn>.<Tb>
2478 USHLL<Q> <Vd>.<Ta>, <Vn>.<Tb>, #0. */
2480 convert_shll_to_xtl (aarch64_inst
*inst
)
2482 if (inst
->operands
[2].imm
.value
== 0)
2484 inst
->operands
[2].type
= AARCH64_OPND_NIL
;
2491 UBFM <Xd>, <Xn>, #<shift>, #63.
2493 LSR <Xd>, <Xn>, #<shift>. */
2495 convert_bfm_to_sr (aarch64_inst
*inst
)
2499 imms
= inst
->operands
[3].imm
.value
;
2500 val
= inst
->operands
[2].qualifier
== AARCH64_OPND_QLF_imm_0_31
? 31 : 63;
2503 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
2510 /* Convert MOV to ORR. */
2512 convert_orr_to_mov (aarch64_inst
*inst
)
2514 /* MOV <Vd>.<T>, <Vn>.<T>
2516 ORR <Vd>.<T>, <Vn>.<T>, <Vn>.<T>. */
2517 if (inst
->operands
[1].reg
.regno
== inst
->operands
[2].reg
.regno
)
2519 inst
->operands
[2].type
= AARCH64_OPND_NIL
;
2525 /* When <imms> >= <immr>, the instruction written:
2526 SBFX <Xd>, <Xn>, #<lsb>, #<width>
2528 SBFM <Xd>, <Xn>, #<lsb>, #(<lsb>+<width>-1). */
2531 convert_bfm_to_bfx (aarch64_inst
*inst
)
2535 immr
= inst
->operands
[2].imm
.value
;
2536 imms
= inst
->operands
[3].imm
.value
;
2540 inst
->operands
[2].imm
.value
= lsb
;
2541 inst
->operands
[3].imm
.value
= imms
+ 1 - lsb
;
2542 /* The two opcodes have different qualifiers for
2543 the immediate operands; reset to help the checking. */
2544 reset_operand_qualifier (inst
, 2);
2545 reset_operand_qualifier (inst
, 3);
2552 /* When <imms> < <immr>, the instruction written:
2553 SBFIZ <Xd>, <Xn>, #<lsb>, #<width>
2555 SBFM <Xd>, <Xn>, #((64-<lsb>)&0x3f), #(<width>-1). */
2558 convert_bfm_to_bfi (aarch64_inst
*inst
)
2560 int64_t immr
, imms
, val
;
2562 immr
= inst
->operands
[2].imm
.value
;
2563 imms
= inst
->operands
[3].imm
.value
;
2564 val
= inst
->operands
[2].qualifier
== AARCH64_OPND_QLF_imm_0_31
? 32 : 64;
2567 inst
->operands
[2].imm
.value
= (val
- immr
) & (val
- 1);
2568 inst
->operands
[3].imm
.value
= imms
+ 1;
2569 /* The two opcodes have different qualifiers for
2570 the immediate operands; reset to help the checking. */
2571 reset_operand_qualifier (inst
, 2);
2572 reset_operand_qualifier (inst
, 3);
2579 /* The instruction written:
2580 BFC <Xd>, #<lsb>, #<width>
2582 BFM <Xd>, XZR, #((64-<lsb>)&0x3f), #(<width>-1). */
2585 convert_bfm_to_bfc (aarch64_inst
*inst
)
2587 int64_t immr
, imms
, val
;
2589 /* Should have been assured by the base opcode value. */
2590 assert (inst
->operands
[1].reg
.regno
== 0x1f);
2592 immr
= inst
->operands
[2].imm
.value
;
2593 imms
= inst
->operands
[3].imm
.value
;
2594 val
= inst
->operands
[2].qualifier
== AARCH64_OPND_QLF_imm_0_31
? 32 : 64;
2597 /* Drop XZR from the second operand. */
2598 copy_operand_info (inst
, 1, 2);
2599 copy_operand_info (inst
, 2, 3);
2600 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
2602 /* Recalculate the immediates. */
2603 inst
->operands
[1].imm
.value
= (val
- immr
) & (val
- 1);
2604 inst
->operands
[2].imm
.value
= imms
+ 1;
2606 /* The two opcodes have different qualifiers for the operands; reset to
2607 help the checking. */
2608 reset_operand_qualifier (inst
, 1);
2609 reset_operand_qualifier (inst
, 2);
2610 reset_operand_qualifier (inst
, 3);
2618 /* The instruction written:
2619 LSL <Xd>, <Xn>, #<shift>
2621 UBFM <Xd>, <Xn>, #((64-<shift>)&0x3f), #(63-<shift>). */
2624 convert_ubfm_to_lsl (aarch64_inst
*inst
)
2626 int64_t immr
= inst
->operands
[2].imm
.value
;
2627 int64_t imms
= inst
->operands
[3].imm
.value
;
2629 = inst
->operands
[2].qualifier
== AARCH64_OPND_QLF_imm_0_31
? 31 : 63;
2631 if ((immr
== 0 && imms
== val
) || immr
== imms
+ 1)
2633 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
2634 inst
->operands
[2].imm
.value
= val
- imms
;
2641 /* CINC <Wd>, <Wn>, <cond>
2643 CSINC <Wd>, <Wn>, <Wn>, invert(<cond>)
2644 where <cond> is not AL or NV. */
2647 convert_from_csel (aarch64_inst
*inst
)
2649 if (inst
->operands
[1].reg
.regno
== inst
->operands
[2].reg
.regno
2650 && (inst
->operands
[3].cond
->value
& 0xe) != 0xe)
2652 copy_operand_info (inst
, 2, 3);
2653 inst
->operands
[2].cond
= get_inverted_cond (inst
->operands
[3].cond
);
2654 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
2660 /* CSET <Wd>, <cond>
2662 CSINC <Wd>, WZR, WZR, invert(<cond>)
2663 where <cond> is not AL or NV. */
2666 convert_csinc_to_cset (aarch64_inst
*inst
)
2668 if (inst
->operands
[1].reg
.regno
== 0x1f
2669 && inst
->operands
[2].reg
.regno
== 0x1f
2670 && (inst
->operands
[3].cond
->value
& 0xe) != 0xe)
2672 copy_operand_info (inst
, 1, 3);
2673 inst
->operands
[1].cond
= get_inverted_cond (inst
->operands
[3].cond
);
2674 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
2675 inst
->operands
[2].type
= AARCH64_OPND_NIL
;
2683 MOVZ <Wd>, #<imm16>, LSL #<shift>.
2685 A disassembler may output ORR, MOVZ and MOVN as a MOV mnemonic, except when
2686 ORR has an immediate that could be generated by a MOVZ or MOVN instruction,
2687 or where a MOVN has an immediate that could be encoded by MOVZ, or where
2688 MOVZ/MOVN #0 have a shift amount other than LSL #0, in which case the
2689 machine-instruction mnemonic must be used. */
2692 convert_movewide_to_mov (aarch64_inst
*inst
)
2694 uint64_t value
= inst
->operands
[1].imm
.value
;
2695 /* MOVZ/MOVN #0 have a shift amount other than LSL #0. */
2696 if (value
== 0 && inst
->operands
[1].shifter
.amount
!= 0)
2698 inst
->operands
[1].type
= AARCH64_OPND_IMM_MOV
;
2699 inst
->operands
[1].shifter
.kind
= AARCH64_MOD_NONE
;
2700 value
<<= inst
->operands
[1].shifter
.amount
;
2701 /* As an alias convertor, it has to be clear that the INST->OPCODE
2702 is the opcode of the real instruction. */
2703 if (inst
->opcode
->op
== OP_MOVN
)
2705 int is32
= inst
->operands
[0].qualifier
== AARCH64_OPND_QLF_W
;
2707 /* A MOVN has an immediate that could be encoded by MOVZ. */
2708 if (aarch64_wide_constant_p (value
, is32
, NULL
))
2711 inst
->operands
[1].imm
.value
= value
;
2712 inst
->operands
[1].shifter
.amount
= 0;
2718 ORR <Wd>, WZR, #<imm>.
2720 A disassembler may output ORR, MOVZ and MOVN as a MOV mnemonic, except when
2721 ORR has an immediate that could be generated by a MOVZ or MOVN instruction,
2722 or where a MOVN has an immediate that could be encoded by MOVZ, or where
2723 MOVZ/MOVN #0 have a shift amount other than LSL #0, in which case the
2724 machine-instruction mnemonic must be used. */
2727 convert_movebitmask_to_mov (aarch64_inst
*inst
)
2732 /* Should have been assured by the base opcode value. */
2733 assert (inst
->operands
[1].reg
.regno
== 0x1f);
2734 copy_operand_info (inst
, 1, 2);
2735 is32
= inst
->operands
[0].qualifier
== AARCH64_OPND_QLF_W
;
2736 inst
->operands
[1].type
= AARCH64_OPND_IMM_MOV
;
2737 value
= inst
->operands
[1].imm
.value
;
2738 /* ORR has an immediate that could be generated by a MOVZ or MOVN
2740 if (inst
->operands
[0].reg
.regno
!= 0x1f
2741 && (aarch64_wide_constant_p (value
, is32
, NULL
)
2742 || aarch64_wide_constant_p (~value
, is32
, NULL
)))
2745 inst
->operands
[2].type
= AARCH64_OPND_NIL
;
2749 /* Some alias opcodes are disassembled by being converted from their real-form.
2750 N.B. INST->OPCODE is the real opcode rather than the alias. */
2753 convert_to_alias (aarch64_inst
*inst
, const aarch64_opcode
*alias
)
2759 return convert_bfm_to_sr (inst
);
2761 return convert_ubfm_to_lsl (inst
);
2765 return convert_from_csel (inst
);
2768 return convert_csinc_to_cset (inst
);
2772 return convert_bfm_to_bfx (inst
);
2776 return convert_bfm_to_bfi (inst
);
2778 return convert_bfm_to_bfc (inst
);
2780 return convert_orr_to_mov (inst
);
2781 case OP_MOV_IMM_WIDE
:
2782 case OP_MOV_IMM_WIDEN
:
2783 return convert_movewide_to_mov (inst
);
2784 case OP_MOV_IMM_LOG
:
2785 return convert_movebitmask_to_mov (inst
);
2787 return convert_extr_to_ror (inst
);
2792 return convert_shll_to_xtl (inst
);
2799 aarch64_opcode_decode (const aarch64_opcode
*, const aarch64_insn
,
2800 aarch64_inst
*, int, aarch64_operand_error
*errors
);
2802 /* Given the instruction information in *INST, check if the instruction has
2803 any alias form that can be used to represent *INST. If the answer is yes,
2804 update *INST to be in the form of the determined alias. */
2806 /* In the opcode description table, the following flags are used in opcode
2807 entries to help establish the relations between the real and alias opcodes:
2809 F_ALIAS: opcode is an alias
2810 F_HAS_ALIAS: opcode has alias(es)
2813 F_P3: Disassembly preference priority 1-3 (the larger the
2814 higher). If nothing is specified, it is the priority
2815 0 by default, i.e. the lowest priority.
2817 Although the relation between the machine and the alias instructions are not
2818 explicitly described, it can be easily determined from the base opcode
2819 values, masks and the flags F_ALIAS and F_HAS_ALIAS in their opcode
2820 description entries:
2822 The mask of an alias opcode must be equal to or a super-set (i.e. more
2823 constrained) of that of the aliased opcode; so is the base opcode value.
2825 if (opcode_has_alias (real) && alias_opcode_p (opcode)
2826 && (opcode->mask & real->mask) == real->mask
2827 && (real->mask & opcode->opcode) == (real->mask & real->opcode))
2828 then OPCODE is an alias of, and only of, the REAL instruction
2830 The alias relationship is forced flat-structured to keep related algorithm
2831 simple; an opcode entry cannot be flagged with both F_ALIAS and F_HAS_ALIAS.
2833 During the disassembling, the decoding decision tree (in
2834 opcodes/aarch64-dis-2.c) always returns an machine instruction opcode entry;
2835 if the decoding of such a machine instruction succeeds (and -Mno-aliases is
2836 not specified), the disassembler will check whether there is any alias
2837 instruction exists for this real instruction. If there is, the disassembler
2838 will try to disassemble the 32-bit binary again using the alias's rule, or
2839 try to convert the IR to the form of the alias. In the case of the multiple
2840 aliases, the aliases are tried one by one from the highest priority
2841 (currently the flag F_P3) to the lowest priority (no priority flag), and the
2842 first succeeds first adopted.
2844 You may ask why there is a need for the conversion of IR from one form to
2845 another in handling certain aliases. This is because on one hand it avoids
2846 adding more operand code to handle unusual encoding/decoding; on other
2847 hand, during the disassembling, the conversion is an effective approach to
2848 check the condition of an alias (as an alias may be adopted only if certain
2849 conditions are met).
2851 In order to speed up the alias opcode lookup, aarch64-gen has preprocessed
2852 aarch64_opcode_table and generated aarch64_find_alias_opcode and
2853 aarch64_find_next_alias_opcode (in opcodes/aarch64-dis-2.c) to help. */
2856 determine_disassembling_preference (struct aarch64_inst
*inst
,
2857 aarch64_operand_error
*errors
)
2859 const aarch64_opcode
*opcode
;
2860 const aarch64_opcode
*alias
;
2862 opcode
= inst
->opcode
;
2864 /* This opcode does not have an alias, so use itself. */
2865 if (!opcode_has_alias (opcode
))
2868 alias
= aarch64_find_alias_opcode (opcode
);
2871 #ifdef DEBUG_AARCH64
2874 const aarch64_opcode
*tmp
= alias
;
2875 printf ("#### LIST orderd: ");
2878 printf ("%s, ", tmp
->name
);
2879 tmp
= aarch64_find_next_alias_opcode (tmp
);
2883 #endif /* DEBUG_AARCH64 */
2885 for (; alias
; alias
= aarch64_find_next_alias_opcode (alias
))
2887 DEBUG_TRACE ("try %s", alias
->name
);
2888 assert (alias_opcode_p (alias
) || opcode_has_alias (opcode
));
2890 /* An alias can be a pseudo opcode which will never be used in the
2891 disassembly, e.g. BIC logical immediate is such a pseudo opcode
2893 if (pseudo_opcode_p (alias
))
2895 DEBUG_TRACE ("skip pseudo %s", alias
->name
);
2899 if ((inst
->value
& alias
->mask
) != alias
->opcode
)
2901 DEBUG_TRACE ("skip %s as base opcode not match", alias
->name
);
2905 if (!AARCH64_CPU_HAS_FEATURE (arch_variant
, *alias
->avariant
))
2907 DEBUG_TRACE ("skip %s: we're missing features", alias
->name
);
2911 /* No need to do any complicated transformation on operands, if the alias
2912 opcode does not have any operand. */
2913 if (aarch64_num_of_operands (alias
) == 0 && alias
->opcode
== inst
->value
)
2915 DEBUG_TRACE ("succeed with 0-operand opcode %s", alias
->name
);
2916 aarch64_replace_opcode (inst
, alias
);
2919 if (alias
->flags
& F_CONV
)
2922 memcpy (©
, inst
, sizeof (aarch64_inst
));
2923 /* ALIAS is the preference as long as the instruction can be
2924 successfully converted to the form of ALIAS. */
2925 if (convert_to_alias (©
, alias
) == 1)
2927 aarch64_replace_opcode (©
, alias
);
2928 if (aarch64_match_operands_constraint (©
, NULL
) != 1)
2930 DEBUG_TRACE ("FAILED with alias %s ", alias
->name
);
2934 DEBUG_TRACE ("succeed with %s via conversion", alias
->name
);
2935 memcpy (inst
, ©
, sizeof (aarch64_inst
));
2942 /* Directly decode the alias opcode. */
2944 memset (&temp
, '\0', sizeof (aarch64_inst
));
2945 if (aarch64_opcode_decode (alias
, inst
->value
, &temp
, 1, errors
) == 1)
2947 DEBUG_TRACE ("succeed with %s via direct decoding", alias
->name
);
2948 memcpy (inst
, &temp
, sizeof (aarch64_inst
));
2955 /* Some instructions (including all SVE ones) use the instruction class
2956 to describe how a qualifiers_list index is represented in the instruction
2957 encoding. If INST is such an instruction, decode the appropriate fields
2958 and fill in the operand qualifiers accordingly. Return true if no
2959 problems are found. */
2962 aarch64_decode_variant_using_iclass (aarch64_inst
*inst
)
2967 switch (inst
->opcode
->iclass
)
2970 variant
= extract_fields (inst
->value
, 0, 2, FLD_size
, FLD_SVE_M_14
);
2974 i
= extract_fields (inst
->value
, 0, 2, FLD_SVE_tszh
, FLD_imm5
);
2977 while ((i
& 1) == 0)
2985 /* Pick the smallest applicable element size. */
2986 if ((inst
->value
& 0x20600) == 0x600)
2988 else if ((inst
->value
& 0x20400) == 0x400)
2990 else if ((inst
->value
& 0x20000) == 0)
2997 /* sve_misc instructions have only a single variant. */
3001 variant
= extract_fields (inst
->value
, 0, 2, FLD_size
, FLD_SVE_M_16
);
3005 variant
= extract_field (FLD_SVE_M_4
, inst
->value
, 0);
3008 case sve_shift_pred
:
3009 i
= extract_fields (inst
->value
, 0, 2, FLD_SVE_tszh
, FLD_SVE_tszl_8
);
3020 case sve_shift_unpred
:
3021 i
= extract_fields (inst
->value
, 0, 2, FLD_SVE_tszh
, FLD_SVE_tszl_19
);
3025 variant
= extract_field (FLD_size
, inst
->value
, 0);
3031 variant
= extract_field (FLD_size
, inst
->value
, 0);
3035 i
= extract_field (FLD_size
, inst
->value
, 0);
3043 variant
= extract_field (FLD_SVE_sz
, inst
->value
, 0);
3047 variant
= extract_field (FLD_SVE_sz2
, inst
->value
, 0);
3051 i
= extract_field (FLD_SVE_size
, inst
->value
, 0);
3058 /* Ignore low bit of this field since that is set in the opcode for
3059 instructions of this iclass. */
3060 i
= (extract_field (FLD_size
, inst
->value
, 0) & 2);
3064 case sve_shift_tsz_bhsd
:
3065 i
= extract_fields (inst
->value
, 0, 2, FLD_SVE_tszh
, FLD_SVE_tszl_19
);
3075 case sve_size_tsz_bhs
:
3076 i
= extract_fields (inst
->value
, 0, 2, FLD_SVE_sz
, FLD_SVE_tszl_19
);
3088 case sve_shift_tsz_hsd
:
3089 i
= extract_fields (inst
->value
, 0, 2, FLD_SVE_sz
, FLD_SVE_tszl_19
);
3100 /* No mapping between instruction class and qualifiers. */
3104 for (i
= 0; i
< AARCH64_MAX_OPND_NUM
; ++i
)
3105 inst
->operands
[i
].qualifier
= inst
->opcode
->qualifiers_list
[variant
][i
];
3108 /* Decode the CODE according to OPCODE; fill INST. Return 0 if the decoding
3109 fails, which meanes that CODE is not an instruction of OPCODE; otherwise
3112 If OPCODE has alias(es) and NOALIASES_P is 0, an alias opcode may be
3113 determined and used to disassemble CODE; this is done just before the
3117 aarch64_opcode_decode (const aarch64_opcode
*opcode
, const aarch64_insn code
,
3118 aarch64_inst
*inst
, int noaliases_p
,
3119 aarch64_operand_error
*errors
)
3123 DEBUG_TRACE ("enter with %s", opcode
->name
);
3125 assert (opcode
&& inst
);
3128 memset (inst
, '\0', sizeof (aarch64_inst
));
3130 /* Check the base opcode. */
3131 if ((code
& opcode
->mask
) != (opcode
->opcode
& opcode
->mask
))
3133 DEBUG_TRACE ("base opcode match FAIL");
3137 inst
->opcode
= opcode
;
3140 /* Assign operand codes and indexes. */
3141 for (i
= 0; i
< AARCH64_MAX_OPND_NUM
; ++i
)
3143 if (opcode
->operands
[i
] == AARCH64_OPND_NIL
)
3145 inst
->operands
[i
].type
= opcode
->operands
[i
];
3146 inst
->operands
[i
].idx
= i
;
3149 /* Call the opcode decoder indicated by flags. */
3150 if (opcode_has_special_coder (opcode
) && do_special_decoding (inst
) == 0)
3152 DEBUG_TRACE ("opcode flag-based decoder FAIL");
3156 /* Possibly use the instruction class to determine the correct
3158 if (!aarch64_decode_variant_using_iclass (inst
))
3160 DEBUG_TRACE ("iclass-based decoder FAIL");
3164 /* Call operand decoders. */
3165 for (i
= 0; i
< AARCH64_MAX_OPND_NUM
; ++i
)
3167 const aarch64_operand
*opnd
;
3168 enum aarch64_opnd type
;
3170 type
= opcode
->operands
[i
];
3171 if (type
== AARCH64_OPND_NIL
)
3173 opnd
= &aarch64_operands
[type
];
3174 if (operand_has_extractor (opnd
)
3175 && (! aarch64_extract_operand (opnd
, &inst
->operands
[i
], code
, inst
,
3178 DEBUG_TRACE ("operand decoder FAIL at operand %d", i
);
3183 /* If the opcode has a verifier, then check it now. */
3184 if (opcode
->verifier
3185 && opcode
->verifier (inst
, code
, 0, false, errors
, NULL
) != ERR_OK
)
3187 DEBUG_TRACE ("operand verifier FAIL");
3191 /* Match the qualifiers. */
3192 if (aarch64_match_operands_constraint (inst
, NULL
) == 1)
3194 /* Arriving here, the CODE has been determined as a valid instruction
3195 of OPCODE and *INST has been filled with information of this OPCODE
3196 instruction. Before the return, check if the instruction has any
3197 alias and should be disassembled in the form of its alias instead.
3198 If the answer is yes, *INST will be updated. */
3200 determine_disassembling_preference (inst
, errors
);
3201 DEBUG_TRACE ("SUCCESS");
3206 DEBUG_TRACE ("constraint matching FAIL");
3213 /* This does some user-friendly fix-up to *INST. It is currently focus on
3214 the adjustment of qualifiers to help the printed instruction
3215 recognized/understood more easily. */
3218 user_friendly_fixup (aarch64_inst
*inst
)
3220 switch (inst
->opcode
->iclass
)
3223 /* TBNZ Xn|Wn, #uimm6, label
3224 Test and Branch Not Zero: conditionally jumps to label if bit number
3225 uimm6 in register Xn is not zero. The bit number implies the width of
3226 the register, which may be written and should be disassembled as Wn if
3227 uimm is less than 32. Limited to a branch offset range of +/- 32KiB.
3229 if (inst
->operands
[1].imm
.value
< 32)
3230 inst
->operands
[0].qualifier
= AARCH64_OPND_QLF_W
;
3236 /* Decode INSN and fill in *INST the instruction information. An alias
3237 opcode may be filled in *INSN if NOALIASES_P is FALSE. Return zero on
3241 aarch64_decode_insn (aarch64_insn insn
, aarch64_inst
*inst
,
3243 aarch64_operand_error
*errors
)
3245 const aarch64_opcode
*opcode
= aarch64_opcode_lookup (insn
);
3247 #ifdef DEBUG_AARCH64
3250 const aarch64_opcode
*tmp
= opcode
;
3252 DEBUG_TRACE ("opcode lookup:");
3255 aarch64_verbose (" %s", tmp
->name
);
3256 tmp
= aarch64_find_next_opcode (tmp
);
3259 #endif /* DEBUG_AARCH64 */
3261 /* A list of opcodes may have been found, as aarch64_opcode_lookup cannot
3262 distinguish some opcodes, e.g. SSHR and MOVI, which almost share the same
3263 opcode field and value, apart from the difference that one of them has an
3264 extra field as part of the opcode, but such a field is used for operand
3265 encoding in other opcode(s) ('immh' in the case of the example). */
3266 while (opcode
!= NULL
)
3268 /* But only one opcode can be decoded successfully for, as the
3269 decoding routine will check the constraint carefully. */
3270 if (aarch64_opcode_decode (opcode
, insn
, inst
, noaliases_p
, errors
) == 1)
3272 opcode
= aarch64_find_next_opcode (opcode
);
3278 /* Print operands. */
3281 print_operands (bfd_vma pc
, const aarch64_opcode
*opcode
,
3282 const aarch64_opnd_info
*opnds
, struct disassemble_info
*info
,
3286 int i
, pcrel_p
, num_printed
;
3287 for (i
= 0, num_printed
= 0; i
< AARCH64_MAX_OPND_NUM
; ++i
)
3290 /* We regard the opcode operand info more, however we also look into
3291 the inst->operands to support the disassembling of the optional
3293 The two operand code should be the same in all cases, apart from
3294 when the operand can be optional. */
3295 if (opcode
->operands
[i
] == AARCH64_OPND_NIL
3296 || opnds
[i
].type
== AARCH64_OPND_NIL
)
3299 /* Generate the operand string in STR. */
3300 aarch64_print_operand (str
, sizeof (str
), pc
, opcode
, opnds
, i
, &pcrel_p
,
3301 &info
->target
, ¬es
, arch_variant
);
3303 /* Print the delimiter (taking account of omitted operand(s)). */
3305 (*info
->fprintf_func
) (info
->stream
, "%s",
3306 num_printed
++ == 0 ? "\t" : ", ");
3308 /* Print the operand. */
3310 (*info
->print_address_func
) (info
->target
, info
);
3312 (*info
->fprintf_func
) (info
->stream
, "%s", str
);
3315 if (notes
&& !no_notes
)
3318 (*info
->fprintf_func
) (info
->stream
, " // note: %s", notes
);
3322 /* Set NAME to a copy of INST's mnemonic with the "." suffix removed. */
3325 remove_dot_suffix (char *name
, const aarch64_inst
*inst
)
3330 ptr
= strchr (inst
->opcode
->name
, '.');
3331 assert (ptr
&& inst
->cond
);
3332 len
= ptr
- inst
->opcode
->name
;
3334 strncpy (name
, inst
->opcode
->name
, len
);
3338 /* Print the instruction mnemonic name. */
3341 print_mnemonic_name (const aarch64_inst
*inst
, struct disassemble_info
*info
)
3343 if (inst
->opcode
->flags
& F_COND
)
3345 /* For instructions that are truly conditionally executed, e.g. b.cond,
3346 prepare the full mnemonic name with the corresponding condition
3350 remove_dot_suffix (name
, inst
);
3351 (*info
->fprintf_func
) (info
->stream
, "%s.%s", name
, inst
->cond
->names
[0]);
3354 (*info
->fprintf_func
) (info
->stream
, "%s", inst
->opcode
->name
);
3357 /* Decide whether we need to print a comment after the operands of
3358 instruction INST. */
3361 print_comment (const aarch64_inst
*inst
, struct disassemble_info
*info
)
3363 if (inst
->opcode
->flags
& F_COND
)
3366 unsigned int i
, num_conds
;
3368 remove_dot_suffix (name
, inst
);
3369 num_conds
= ARRAY_SIZE (inst
->cond
->names
);
3370 for (i
= 1; i
< num_conds
&& inst
->cond
->names
[i
]; ++i
)
3371 (*info
->fprintf_func
) (info
->stream
, "%s %s.%s",
3372 i
== 1 ? " //" : ",",
3373 name
, inst
->cond
->names
[i
]);
3377 /* Build notes from verifiers into a string for printing. */
3380 print_verifier_notes (aarch64_operand_error
*detail
,
3381 struct disassemble_info
*info
)
3386 /* The output of the verifier cannot be a fatal error, otherwise the assembly
3387 would not have succeeded. We can safely ignore these. */
3388 assert (detail
->non_fatal
);
3390 (*info
->fprintf_func
) (info
->stream
, " // note: ");
3391 switch (detail
->kind
)
3393 case AARCH64_OPDE_A_SHOULD_FOLLOW_B
:
3394 (*info
->fprintf_func
) (info
->stream
,
3395 _("this `%s' should have an immediately"
3397 detail
->data
[0].s
, detail
->data
[1].s
);
3400 case AARCH64_OPDE_EXPECTED_A_AFTER_B
:
3401 (*info
->fprintf_func
) (info
->stream
,
3402 _("expected `%s' after previous `%s'"),
3403 detail
->data
[0].s
, detail
->data
[1].s
);
3407 assert (detail
->error
);
3408 (*info
->fprintf_func
) (info
->stream
, "%s", detail
->error
);
3409 if (detail
->index
>= 0)
3410 (*info
->fprintf_func
) (info
->stream
, " at operand %d",
3416 /* Print the instruction according to *INST. */
3419 print_aarch64_insn (bfd_vma pc
, const aarch64_inst
*inst
,
3420 const aarch64_insn code
,
3421 struct disassemble_info
*info
,
3422 aarch64_operand_error
*mismatch_details
)
3424 bool has_notes
= false;
3426 print_mnemonic_name (inst
, info
);
3427 print_operands (pc
, inst
->opcode
, inst
->operands
, info
, &has_notes
);
3428 print_comment (inst
, info
);
3430 /* We've already printed a note, not enough space to print more so exit.
3431 Usually notes shouldn't overlap so it shouldn't happen that we have a note
3432 from a register and instruction at the same time. */
3436 /* Always run constraint verifiers, this is needed because constraints need to
3437 maintain a global state regardless of whether the instruction has the flag
3439 enum err_type result
= verify_constraints (inst
, code
, pc
, false,
3440 mismatch_details
, &insn_sequence
);
3444 print_verifier_notes (mismatch_details
, info
);
3454 /* Entry-point of the instruction disassembler and printer. */
3457 print_insn_aarch64_word (bfd_vma pc
,
3459 struct disassemble_info
*info
,
3460 aarch64_operand_error
*errors
)
3462 static const char *err_msg
[ERR_NR_ENTRIES
+1] =
3465 [ERR_UND
] = "undefined",
3466 [ERR_UNP
] = "unpredictable",
3473 info
->insn_info_valid
= 1;
3474 info
->branch_delay_insns
= 0;
3475 info
->data_size
= 0;
3479 if (info
->flags
& INSN_HAS_RELOC
)
3480 /* If the instruction has a reloc associated with it, then
3481 the offset field in the instruction will actually be the
3482 addend for the reloc. (If we are using REL type relocs).
3483 In such cases, we can ignore the pc when computing
3484 addresses, since the addend is not currently pc-relative. */
3487 ret
= aarch64_decode_insn (word
, &inst
, no_aliases
, errors
);
3489 if (((word
>> 21) & 0x3ff) == 1)
3491 /* RESERVED for ALES. */
3492 assert (ret
!= ERR_OK
);
3501 /* Handle undefined instructions. */
3502 info
->insn_type
= dis_noninsn
;
3503 (*info
->fprintf_func
) (info
->stream
,".inst\t0x%08x ; %s",
3504 word
, err_msg
[ret
]);
3507 user_friendly_fixup (&inst
);
3508 print_aarch64_insn (pc
, &inst
, word
, info
, errors
);
3515 /* Disallow mapping symbols ($x, $d etc) from
3516 being displayed in symbol relative addresses. */
3519 aarch64_symbol_is_valid (asymbol
* sym
,
3520 struct disassemble_info
* info ATTRIBUTE_UNUSED
)
3527 name
= bfd_asymbol_name (sym
);
3531 || (name
[1] != 'x' && name
[1] != 'd')
3532 || (name
[2] != '\0' && name
[2] != '.'));
3535 /* Print data bytes on INFO->STREAM. */
3538 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED
,
3540 struct disassemble_info
*info
,
3541 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
3543 switch (info
->bytes_per_chunk
)
3546 info
->fprintf_func (info
->stream
, ".byte\t0x%02x", word
);
3549 info
->fprintf_func (info
->stream
, ".short\t0x%04x", word
);
3552 info
->fprintf_func (info
->stream
, ".word\t0x%08x", word
);
3559 /* Try to infer the code or data type from a symbol.
3560 Returns nonzero if *MAP_TYPE was set. */
3563 get_sym_code_type (struct disassemble_info
*info
, int n
,
3564 enum map_type
*map_type
)
3567 elf_symbol_type
*es
;
3571 /* If the symbol is in a different section, ignore it. */
3572 if (info
->section
!= NULL
&& info
->section
!= info
->symtab
[n
]->section
)
3575 if (n
>= info
->symtab_size
)
3578 as
= info
->symtab
[n
];
3579 if (bfd_asymbol_flavour (as
) != bfd_target_elf_flavour
)
3581 es
= (elf_symbol_type
*) as
;
3583 type
= ELF_ST_TYPE (es
->internal_elf_sym
.st_info
);
3585 /* If the symbol has function type then use that. */
3586 if (type
== STT_FUNC
)
3588 *map_type
= MAP_INSN
;
3592 /* Check for mapping symbols. */
3593 name
= bfd_asymbol_name(info
->symtab
[n
]);
3595 && (name
[1] == 'x' || name
[1] == 'd')
3596 && (name
[2] == '\0' || name
[2] == '.'))
3598 *map_type
= (name
[1] == 'x' ? MAP_INSN
: MAP_DATA
);
3605 /* Set the feature bits in arch_variant in order to get the correct disassembly
3606 for the chosen architecture variant.
3608 Currently we only restrict disassembly for Armv8-R and otherwise enable all
3609 non-R-profile features. */
3611 select_aarch64_variant (unsigned mach
)
3615 case bfd_mach_aarch64_8R
:
3616 arch_variant
= AARCH64_ARCH_V8_R
;
3619 arch_variant
= AARCH64_ANY
& ~(AARCH64_FEATURE_V8_R
);
3623 /* Entry-point of the AArch64 disassembler. */
3626 print_insn_aarch64 (bfd_vma pc
,
3627 struct disassemble_info
*info
)
3629 bfd_byte buffer
[INSNLEN
];
3631 void (*printer
) (bfd_vma
, uint32_t, struct disassemble_info
*,
3632 aarch64_operand_error
*);
3634 unsigned int size
= 4;
3636 aarch64_operand_error errors
;
3637 static bool set_features
;
3639 if (info
->disassembler_options
)
3641 set_default_aarch64_dis_options (info
);
3643 parse_aarch64_dis_options (info
->disassembler_options
);
3645 /* To avoid repeated parsing of these options, we remove them here. */
3646 info
->disassembler_options
= NULL
;
3651 select_aarch64_variant (info
->mach
);
3652 set_features
= true;
3655 /* Aarch64 instructions are always little-endian */
3656 info
->endian_code
= BFD_ENDIAN_LITTLE
;
3658 /* Default to DATA. A text section is required by the ABI to contain an
3659 INSN mapping symbol at the start. A data section has no such
3660 requirement, hence if no mapping symbol is found the section must
3661 contain only data. This however isn't very useful if the user has
3662 fully stripped the binaries. If this is the case use the section
3663 attributes to determine the default. If we have no section default to
3664 INSN as well, as we may be disassembling some raw bytes on a baremetal
3665 HEX file or similar. */
3666 enum map_type type
= MAP_DATA
;
3667 if ((info
->section
&& info
->section
->flags
& SEC_CODE
) || !info
->section
)
3670 /* First check the full symtab for a mapping symbol, even if there
3671 are no usable non-mapping symbols for this address. */
3672 if (info
->symtab_size
!= 0
3673 && bfd_asymbol_flavour (*info
->symtab
) == bfd_target_elf_flavour
)
3676 bfd_vma addr
, section_vma
= 0;
3677 bool can_use_search_opt_p
;
3680 if (pc
<= last_mapping_addr
)
3681 last_mapping_sym
= -1;
3683 /* Start scanning at the start of the function, or wherever
3684 we finished last time. */
3685 n
= info
->symtab_pos
+ 1;
3687 /* If the last stop offset is different from the current one it means we
3688 are disassembling a different glob of bytes. As such the optimization
3689 would not be safe and we should start over. */
3690 can_use_search_opt_p
= last_mapping_sym
>= 0
3691 && info
->stop_offset
== last_stop_offset
;
3693 if (n
>= last_mapping_sym
&& can_use_search_opt_p
)
3694 n
= last_mapping_sym
;
3696 /* Look down while we haven't passed the location being disassembled.
3697 The reason for this is that there's no defined order between a symbol
3698 and an mapping symbol that may be at the same address. We may have to
3699 look at least one position ahead. */
3700 for (; n
< info
->symtab_size
; n
++)
3702 addr
= bfd_asymbol_value (info
->symtab
[n
]);
3705 if (get_sym_code_type (info
, n
, &type
))
3714 n
= info
->symtab_pos
;
3715 if (n
>= last_mapping_sym
&& can_use_search_opt_p
)
3716 n
= last_mapping_sym
;
3718 /* No mapping symbol found at this address. Look backwards
3719 for a preceeding one, but don't go pass the section start
3720 otherwise a data section with no mapping symbol can pick up
3721 a text mapping symbol of a preceeding section. The documentation
3722 says section can be NULL, in which case we will seek up all the
3725 section_vma
= info
->section
->vma
;
3729 addr
= bfd_asymbol_value (info
->symtab
[n
]);
3730 if (addr
< section_vma
)
3733 if (get_sym_code_type (info
, n
, &type
))
3742 last_mapping_sym
= last_sym
;
3744 last_stop_offset
= info
->stop_offset
;
3746 /* Look a little bit ahead to see if we should print out
3747 less than four bytes of data. If there's a symbol,
3748 mapping or otherwise, after two bytes then don't
3750 if (last_type
== MAP_DATA
)
3752 size
= 4 - (pc
& 3);
3753 for (n
= last_sym
+ 1; n
< info
->symtab_size
; n
++)
3755 addr
= bfd_asymbol_value (info
->symtab
[n
]);
3758 if (addr
- pc
< size
)
3763 /* If the next symbol is after three bytes, we need to
3764 print only part of the data, so that we can use either
3767 size
= (pc
& 1) ? 1 : 2;
3773 /* PR 10263: Disassemble data if requested to do so by the user. */
3774 if (last_type
== MAP_DATA
&& ((info
->flags
& DISASSEMBLE_DATA
) == 0))
3776 /* size was set above. */
3777 info
->bytes_per_chunk
= size
;
3778 info
->display_endian
= info
->endian
;
3779 printer
= print_insn_data
;
3783 info
->bytes_per_chunk
= size
= INSNLEN
;
3784 info
->display_endian
= info
->endian_code
;
3785 printer
= print_insn_aarch64_word
;
3788 status
= (*info
->read_memory_func
) (pc
, buffer
, size
, info
);
3791 (*info
->memory_error_func
) (status
, pc
, info
);
3795 data
= bfd_get_bits (buffer
, size
* 8,
3796 info
->display_endian
== BFD_ENDIAN_BIG
);
3798 (*printer
) (pc
, data
, info
, &errors
);
3804 print_aarch64_disassembler_options (FILE *stream
)
3806 fprintf (stream
, _("\n\
3807 The following AARCH64 specific disassembler options are supported for use\n\
3808 with the -M switch (multiple options should be separated by commas):\n"));
3810 fprintf (stream
, _("\n\
3811 no-aliases Don't print instruction aliases.\n"));
3813 fprintf (stream
, _("\n\
3814 aliases Do print instruction aliases.\n"));
3816 fprintf (stream
, _("\n\
3817 no-notes Don't print instruction notes.\n"));
3819 fprintf (stream
, _("\n\
3820 notes Do print instruction notes.\n"));
3822 #ifdef DEBUG_AARCH64
3823 fprintf (stream
, _("\n\
3824 debug_dump Temp switch for debug trace.\n"));
3825 #endif /* DEBUG_AARCH64 */
3827 fprintf (stream
, _("\n"));