1 /* aarch64-dis.c -- AArch64 disassembler.
2 Copyright (C) 2009-2018 Free Software Foundation, Inc.
3 Contributed by ARM Ltd.
5 This file is part of the GNU opcodes library.
7 This library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 It is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; see the file COPYING3. If not,
19 see <http://www.gnu.org/licenses/>. */
22 #include "bfd_stdint.h"
23 #include "disassemble.h"
24 #include "libiberty.h"
26 #include "aarch64-dis.h"
36 /* Cached mapping symbol state. */
43 static enum map_type last_type
;
44 static int last_mapping_sym
= -1;
45 static bfd_vma last_mapping_addr
= 0;
48 static int no_aliases
= 0; /* If set disassemble as most general inst. */
52 set_default_aarch64_dis_options (struct disassemble_info
*info ATTRIBUTE_UNUSED
)
57 parse_aarch64_dis_option (const char *option
, unsigned int len ATTRIBUTE_UNUSED
)
59 /* Try to match options that are simple flags */
60 if (CONST_STRNEQ (option
, "no-aliases"))
66 if (CONST_STRNEQ (option
, "aliases"))
73 if (CONST_STRNEQ (option
, "debug_dump"))
78 #endif /* DEBUG_AARCH64 */
81 opcodes_error_handler (_("unrecognised disassembler option: %s"), option
);
85 parse_aarch64_dis_options (const char *options
)
87 const char *option_end
;
92 while (*options
!= '\0')
94 /* Skip empty options. */
101 /* We know that *options is neither NUL or a comma. */
102 option_end
= options
+ 1;
103 while (*option_end
!= ',' && *option_end
!= '\0')
106 parse_aarch64_dis_option (options
, option_end
- options
);
108 /* Go on to the next one. If option_end points to a comma, it
109 will be skipped above. */
110 options
= option_end
;
114 /* Functions doing the instruction disassembling. */
116 /* The unnamed arguments consist of the number of fields and information about
117 these fields where the VALUE will be extracted from CODE and returned.
118 MASK can be zero or the base mask of the opcode.
120 N.B. the fields are required to be in such an order than the most signficant
121 field for VALUE comes the first, e.g. the <index> in
122 SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
123 is encoded in H:L:M in some cases, the fields H:L:M should be passed in
124 the order of H, L, M. */
127 extract_fields (aarch64_insn code
, aarch64_insn mask
, ...)
130 const aarch64_field
*field
;
131 enum aarch64_field_kind kind
;
135 num
= va_arg (va
, uint32_t);
137 aarch64_insn value
= 0x0;
140 kind
= va_arg (va
, enum aarch64_field_kind
);
141 field
= &fields
[kind
];
142 value
<<= field
->width
;
143 value
|= extract_field (kind
, code
, mask
);
148 /* Extract the value of all fields in SELF->fields from instruction CODE.
149 The least significant bit comes from the final field. */
152 extract_all_fields (const aarch64_operand
*self
, aarch64_insn code
)
156 enum aarch64_field_kind kind
;
159 for (i
= 0; i
< ARRAY_SIZE (self
->fields
) && self
->fields
[i
] != FLD_NIL
; ++i
)
161 kind
= self
->fields
[i
];
162 value
<<= fields
[kind
].width
;
163 value
|= extract_field (kind
, code
, 0);
168 /* Sign-extend bit I of VALUE. */
169 static inline int32_t
170 sign_extend (aarch64_insn value
, unsigned i
)
172 uint32_t ret
= value
;
175 if ((value
>> i
) & 0x1)
177 uint32_t val
= (uint32_t)(-1) << i
;
180 return (int32_t) ret
;
183 /* N.B. the following inline helpfer functions create a dependency on the
184 order of operand qualifier enumerators. */
186 /* Given VALUE, return qualifier for a general purpose register. */
187 static inline enum aarch64_opnd_qualifier
188 get_greg_qualifier_from_value (aarch64_insn value
)
190 enum aarch64_opnd_qualifier qualifier
= AARCH64_OPND_QLF_W
+ value
;
192 && aarch64_get_qualifier_standard_value (qualifier
) == value
);
196 /* Given VALUE, return qualifier for a vector register. This does not support
197 decoding instructions that accept the 2H vector type. */
199 static inline enum aarch64_opnd_qualifier
200 get_vreg_qualifier_from_value (aarch64_insn value
)
202 enum aarch64_opnd_qualifier qualifier
= AARCH64_OPND_QLF_V_8B
+ value
;
204 /* Instructions using vector type 2H should not call this function. Skip over
206 if (qualifier
>= AARCH64_OPND_QLF_V_2H
)
210 && aarch64_get_qualifier_standard_value (qualifier
) == value
);
214 /* Given VALUE, return qualifier for an FP or AdvSIMD scalar register. */
215 static inline enum aarch64_opnd_qualifier
216 get_sreg_qualifier_from_value (aarch64_insn value
)
218 enum aarch64_opnd_qualifier qualifier
= AARCH64_OPND_QLF_S_B
+ value
;
221 && aarch64_get_qualifier_standard_value (qualifier
) == value
);
225 /* Given the instruction in *INST which is probably half way through the
226 decoding and our caller wants to know the expected qualifier for operand
227 I. Return such a qualifier if we can establish it; otherwise return
228 AARCH64_OPND_QLF_NIL. */
230 static aarch64_opnd_qualifier_t
231 get_expected_qualifier (const aarch64_inst
*inst
, int i
)
233 aarch64_opnd_qualifier_seq_t qualifiers
;
234 /* Should not be called if the qualifier is known. */
235 assert (inst
->operands
[i
].qualifier
== AARCH64_OPND_QLF_NIL
);
236 if (aarch64_find_best_match (inst
, inst
->opcode
->qualifiers_list
,
238 return qualifiers
[i
];
240 return AARCH64_OPND_QLF_NIL
;
243 /* Operand extractors. */
246 aarch64_ext_regno (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
247 const aarch64_insn code
,
248 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
249 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
251 info
->reg
.regno
= extract_field (self
->fields
[0], code
, 0);
256 aarch64_ext_regno_pair (const aarch64_operand
*self ATTRIBUTE_UNUSED
, aarch64_opnd_info
*info
,
257 const aarch64_insn code ATTRIBUTE_UNUSED
,
258 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
259 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
261 assert (info
->idx
== 1
263 info
->reg
.regno
= inst
->operands
[info
->idx
- 1].reg
.regno
+ 1;
267 /* e.g. IC <ic_op>{, <Xt>}. */
269 aarch64_ext_regrt_sysins (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
270 const aarch64_insn code
,
271 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
272 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
274 info
->reg
.regno
= extract_field (self
->fields
[0], code
, 0);
275 assert (info
->idx
== 1
276 && (aarch64_get_operand_class (inst
->operands
[0].type
)
277 == AARCH64_OPND_CLASS_SYSTEM
));
278 /* This will make the constraint checking happy and more importantly will
279 help the disassembler determine whether this operand is optional or
281 info
->present
= aarch64_sys_ins_reg_has_xt (inst
->operands
[0].sysins_op
);
286 /* e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]. */
288 aarch64_ext_reglane (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
289 const aarch64_insn code
,
290 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
291 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
294 info
->reglane
.regno
= extract_field (self
->fields
[0], code
,
297 /* Index and/or type. */
298 if (inst
->opcode
->iclass
== asisdone
299 || inst
->opcode
->iclass
== asimdins
)
301 if (info
->type
== AARCH64_OPND_En
302 && inst
->opcode
->operands
[0] == AARCH64_OPND_Ed
)
305 /* index2 for e.g. INS <Vd>.<Ts>[<index1>], <Vn>.<Ts>[<index2>]. */
306 assert (info
->idx
== 1); /* Vn */
307 aarch64_insn value
= extract_field (FLD_imm4
, code
, 0);
308 /* Depend on AARCH64_OPND_Ed to determine the qualifier. */
309 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
310 shift
= get_logsz (aarch64_get_qualifier_esize (info
->qualifier
));
311 info
->reglane
.index
= value
>> shift
;
315 /* index and type for e.g. DUP <V><d>, <Vn>.<T>[<index>].
323 aarch64_insn value
= extract_field (FLD_imm5
, code
, 0);
324 while (++pos
<= 3 && (value
& 0x1) == 0)
328 info
->qualifier
= get_sreg_qualifier_from_value (pos
);
329 info
->reglane
.index
= (unsigned) (value
>> 1);
332 else if (inst
->opcode
->iclass
== dotproduct
)
334 /* Need information in other operand(s) to help decoding. */
335 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
336 switch (info
->qualifier
)
338 case AARCH64_OPND_QLF_S_4B
:
340 info
->reglane
.index
= extract_fields (code
, 0, 2, FLD_H
, FLD_L
);
341 info
->reglane
.regno
&= 0x1f;
347 else if (inst
->opcode
->iclass
== cryptosm3
)
349 /* index for e.g. SM3TT2A <Vd>.4S, <Vn>.4S, <Vm>S[<imm2>]. */
350 info
->reglane
.index
= extract_field (FLD_SM3_imm2
, code
, 0);
354 /* Index only for e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
355 or SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]. */
357 /* Need information in other operand(s) to help decoding. */
358 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
359 switch (info
->qualifier
)
361 case AARCH64_OPND_QLF_S_H
:
363 info
->reglane
.index
= extract_fields (code
, 0, 3, FLD_H
, FLD_L
,
365 info
->reglane
.regno
&= 0xf;
367 case AARCH64_OPND_QLF_S_S
:
369 info
->reglane
.index
= extract_fields (code
, 0, 2, FLD_H
, FLD_L
);
371 case AARCH64_OPND_QLF_S_D
:
373 info
->reglane
.index
= extract_field (FLD_H
, code
, 0);
379 if (inst
->opcode
->op
== OP_FCMLA_ELEM
)
381 /* Complex operand takes two elements. */
382 if (info
->reglane
.index
& 1)
384 info
->reglane
.index
/= 2;
392 aarch64_ext_reglist (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
393 const aarch64_insn code
,
394 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
395 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
398 info
->reglist
.first_regno
= extract_field (self
->fields
[0], code
, 0);
400 info
->reglist
.num_regs
= extract_field (FLD_len
, code
, 0) + 1;
404 /* Decode Rt and opcode fields of Vt in AdvSIMD load/store instructions. */
406 aarch64_ext_ldst_reglist (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
407 aarch64_opnd_info
*info
, const aarch64_insn code
,
408 const aarch64_inst
*inst
,
409 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
412 /* Number of elements in each structure to be loaded/stored. */
413 unsigned expected_num
= get_opcode_dependent_value (inst
->opcode
);
417 unsigned is_reserved
;
419 unsigned num_elements
;
435 info
->reglist
.first_regno
= extract_field (FLD_Rt
, code
, 0);
437 value
= extract_field (FLD_opcode
, code
, 0);
438 /* PR 21595: Check for a bogus value. */
439 if (value
>= ARRAY_SIZE (data
))
441 if (expected_num
!= data
[value
].num_elements
|| data
[value
].is_reserved
)
443 info
->reglist
.num_regs
= data
[value
].num_regs
;
448 /* Decode Rt and S fields of Vt in AdvSIMD load single structure to all
449 lanes instructions. */
451 aarch64_ext_ldst_reglist_r (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
452 aarch64_opnd_info
*info
, const aarch64_insn code
,
453 const aarch64_inst
*inst
,
454 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
459 info
->reglist
.first_regno
= extract_field (FLD_Rt
, code
, 0);
461 value
= extract_field (FLD_S
, code
, 0);
463 /* Number of registers is equal to the number of elements in
464 each structure to be loaded/stored. */
465 info
->reglist
.num_regs
= get_opcode_dependent_value (inst
->opcode
);
466 assert (info
->reglist
.num_regs
>= 1 && info
->reglist
.num_regs
<= 4);
468 /* Except when it is LD1R. */
469 if (info
->reglist
.num_regs
== 1 && value
== (aarch64_insn
) 1)
470 info
->reglist
.num_regs
= 2;
475 /* Decode Q, opcode<2:1>, S, size and Rt fields of Vt in AdvSIMD
476 load/store single element instructions. */
478 aarch64_ext_ldst_elemlist (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
479 aarch64_opnd_info
*info
, const aarch64_insn code
,
480 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
481 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
483 aarch64_field field
= {0, 0};
484 aarch64_insn QSsize
; /* fields Q:S:size. */
485 aarch64_insn opcodeh2
; /* opcode<2:1> */
488 info
->reglist
.first_regno
= extract_field (FLD_Rt
, code
, 0);
490 /* Decode the index, opcode<2:1> and size. */
491 gen_sub_field (FLD_asisdlso_opcode
, 1, 2, &field
);
492 opcodeh2
= extract_field_2 (&field
, code
, 0);
493 QSsize
= extract_fields (code
, 0, 3, FLD_Q
, FLD_S
, FLD_vldst_size
);
497 info
->qualifier
= AARCH64_OPND_QLF_S_B
;
498 /* Index encoded in "Q:S:size". */
499 info
->reglist
.index
= QSsize
;
505 info
->qualifier
= AARCH64_OPND_QLF_S_H
;
506 /* Index encoded in "Q:S:size<1>". */
507 info
->reglist
.index
= QSsize
>> 1;
510 if ((QSsize
>> 1) & 0x1)
513 if ((QSsize
& 0x1) == 0)
515 info
->qualifier
= AARCH64_OPND_QLF_S_S
;
516 /* Index encoded in "Q:S". */
517 info
->reglist
.index
= QSsize
>> 2;
521 if (extract_field (FLD_S
, code
, 0))
524 info
->qualifier
= AARCH64_OPND_QLF_S_D
;
525 /* Index encoded in "Q". */
526 info
->reglist
.index
= QSsize
>> 3;
533 info
->reglist
.has_index
= 1;
534 info
->reglist
.num_regs
= 0;
535 /* Number of registers is equal to the number of elements in
536 each structure to be loaded/stored. */
537 info
->reglist
.num_regs
= get_opcode_dependent_value (inst
->opcode
);
538 assert (info
->reglist
.num_regs
>= 1 && info
->reglist
.num_regs
<= 4);
543 /* Decode fields immh:immb and/or Q for e.g.
544 SSHR <Vd>.<T>, <Vn>.<T>, #<shift>
545 or SSHR <V><d>, <V><n>, #<shift>. */
548 aarch64_ext_advsimd_imm_shift (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
549 aarch64_opnd_info
*info
, const aarch64_insn code
,
550 const aarch64_inst
*inst
,
551 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
554 aarch64_insn Q
, imm
, immh
;
555 enum aarch64_insn_class iclass
= inst
->opcode
->iclass
;
557 immh
= extract_field (FLD_immh
, code
, 0);
560 imm
= extract_fields (code
, 0, 2, FLD_immh
, FLD_immb
);
562 /* Get highest set bit in immh. */
563 while (--pos
>= 0 && (immh
& 0x8) == 0)
566 assert ((iclass
== asimdshf
|| iclass
== asisdshf
)
567 && (info
->type
== AARCH64_OPND_IMM_VLSR
568 || info
->type
== AARCH64_OPND_IMM_VLSL
));
570 if (iclass
== asimdshf
)
572 Q
= extract_field (FLD_Q
, code
, 0);
574 0000 x SEE AdvSIMD modified immediate
584 get_vreg_qualifier_from_value ((pos
<< 1) | (int) Q
);
587 info
->qualifier
= get_sreg_qualifier_from_value (pos
);
589 if (info
->type
== AARCH64_OPND_IMM_VLSR
)
591 0000 SEE AdvSIMD modified immediate
592 0001 (16-UInt(immh:immb))
593 001x (32-UInt(immh:immb))
594 01xx (64-UInt(immh:immb))
595 1xxx (128-UInt(immh:immb)) */
596 info
->imm
.value
= (16 << pos
) - imm
;
600 0000 SEE AdvSIMD modified immediate
601 0001 (UInt(immh:immb)-8)
602 001x (UInt(immh:immb)-16)
603 01xx (UInt(immh:immb)-32)
604 1xxx (UInt(immh:immb)-64) */
605 info
->imm
.value
= imm
- (8 << pos
);
610 /* Decode shift immediate for e.g. sshr (imm). */
612 aarch64_ext_shll_imm (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
613 aarch64_opnd_info
*info
, const aarch64_insn code
,
614 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
615 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
619 val
= extract_field (FLD_size
, code
, 0);
622 case 0: imm
= 8; break;
623 case 1: imm
= 16; break;
624 case 2: imm
= 32; break;
625 default: return FALSE
;
627 info
->imm
.value
= imm
;
631 /* Decode imm for e.g. BFM <Wd>, <Wn>, #<immr>, #<imms>.
632 value in the field(s) will be extracted as unsigned immediate value. */
634 aarch64_ext_imm (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
635 const aarch64_insn code
,
636 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
637 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
641 imm
= extract_all_fields (self
, code
);
643 if (operand_need_sign_extension (self
))
644 imm
= sign_extend (imm
, get_operand_fields_width (self
) - 1);
646 if (operand_need_shift_by_two (self
))
649 if (info
->type
== AARCH64_OPND_ADDR_ADRP
)
652 info
->imm
.value
= imm
;
656 /* Decode imm and its shifter for e.g. MOVZ <Wd>, #<imm16>{, LSL #<shift>}. */
658 aarch64_ext_imm_half (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
659 const aarch64_insn code
,
660 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
661 aarch64_operand_error
*errors
)
663 aarch64_ext_imm (self
, info
, code
, inst
, errors
);
664 info
->shifter
.kind
= AARCH64_MOD_LSL
;
665 info
->shifter
.amount
= extract_field (FLD_hw
, code
, 0) << 4;
669 /* Decode cmode and "a:b:c:d:e:f:g:h" for e.g.
670 MOVI <Vd>.<T>, #<imm8> {, LSL #<amount>}. */
672 aarch64_ext_advsimd_imm_modified (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
673 aarch64_opnd_info
*info
,
674 const aarch64_insn code
,
675 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
676 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
679 enum aarch64_opnd_qualifier opnd0_qualifier
= inst
->operands
[0].qualifier
;
680 aarch64_field field
= {0, 0};
682 assert (info
->idx
== 1);
684 if (info
->type
== AARCH64_OPND_SIMD_FPIMM
)
687 /* a:b:c:d:e:f:g:h */
688 imm
= extract_fields (code
, 0, 2, FLD_abc
, FLD_defgh
);
689 if (!info
->imm
.is_fp
&& aarch64_get_qualifier_esize (opnd0_qualifier
) == 8)
691 /* Either MOVI <Dd>, #<imm>
692 or MOVI <Vd>.2D, #<imm>.
693 <imm> is a 64-bit immediate
694 'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh',
695 encoded in "a:b:c:d:e:f:g:h". */
697 unsigned abcdefgh
= imm
;
698 for (imm
= 0ull, i
= 0; i
< 8; i
++)
699 if (((abcdefgh
>> i
) & 0x1) != 0)
700 imm
|= 0xffull
<< (8 * i
);
702 info
->imm
.value
= imm
;
705 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
706 switch (info
->qualifier
)
708 case AARCH64_OPND_QLF_NIL
:
710 info
->shifter
.kind
= AARCH64_MOD_NONE
;
712 case AARCH64_OPND_QLF_LSL
:
714 info
->shifter
.kind
= AARCH64_MOD_LSL
;
715 switch (aarch64_get_qualifier_esize (opnd0_qualifier
))
717 case 4: gen_sub_field (FLD_cmode
, 1, 2, &field
); break; /* per word */
718 case 2: gen_sub_field (FLD_cmode
, 1, 1, &field
); break; /* per half */
719 case 1: gen_sub_field (FLD_cmode
, 1, 0, &field
); break; /* per byte */
720 default: assert (0); return FALSE
;
722 /* 00: 0; 01: 8; 10:16; 11:24. */
723 info
->shifter
.amount
= extract_field_2 (&field
, code
, 0) << 3;
725 case AARCH64_OPND_QLF_MSL
:
727 info
->shifter
.kind
= AARCH64_MOD_MSL
;
728 gen_sub_field (FLD_cmode
, 0, 1, &field
); /* per word */
729 info
->shifter
.amount
= extract_field_2 (&field
, code
, 0) ? 16 : 8;
739 /* Decode an 8-bit floating-point immediate. */
741 aarch64_ext_fpimm (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
742 const aarch64_insn code
,
743 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
744 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
746 info
->imm
.value
= extract_all_fields (self
, code
);
751 /* Decode a 1-bit rotate immediate (#90 or #270). */
753 aarch64_ext_imm_rotate1 (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
754 const aarch64_insn code
,
755 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
756 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
758 uint64_t rot
= extract_field (self
->fields
[0], code
, 0);
760 info
->imm
.value
= rot
* 180 + 90;
764 /* Decode a 2-bit rotate immediate (#0, #90, #180 or #270). */
766 aarch64_ext_imm_rotate2 (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
767 const aarch64_insn code
,
768 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
769 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
771 uint64_t rot
= extract_field (self
->fields
[0], code
, 0);
773 info
->imm
.value
= rot
* 90;
777 /* Decode scale for e.g. SCVTF <Dd>, <Wn>, #<fbits>. */
779 aarch64_ext_fbits (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
780 aarch64_opnd_info
*info
, const aarch64_insn code
,
781 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
782 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
784 info
->imm
.value
= 64- extract_field (FLD_scale
, code
, 0);
788 /* Decode arithmetic immediate for e.g.
789 SUBS <Wd>, <Wn|WSP>, #<imm> {, <shift>}. */
791 aarch64_ext_aimm (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
792 aarch64_opnd_info
*info
, const aarch64_insn code
,
793 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
794 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
798 info
->shifter
.kind
= AARCH64_MOD_LSL
;
800 value
= extract_field (FLD_shift
, code
, 0);
803 info
->shifter
.amount
= value
? 12 : 0;
804 /* imm12 (unsigned) */
805 info
->imm
.value
= extract_field (FLD_imm12
, code
, 0);
810 /* Return true if VALUE is a valid logical immediate encoding, storing the
811 decoded value in *RESULT if so. ESIZE is the number of bytes in the
812 decoded immediate. */
814 decode_limm (uint32_t esize
, aarch64_insn value
, int64_t *result
)
820 /* value is N:immr:imms. */
822 R
= (value
>> 6) & 0x3f;
823 N
= (value
>> 12) & 0x1;
825 /* The immediate value is S+1 bits to 1, left rotated by SIMDsize - R
826 (in other words, right rotated by R), then replicated. */
830 mask
= 0xffffffffffffffffull
;
836 case 0x00 ... 0x1f: /* 0xxxxx */ simd_size
= 32; break;
837 case 0x20 ... 0x2f: /* 10xxxx */ simd_size
= 16; S
&= 0xf; break;
838 case 0x30 ... 0x37: /* 110xxx */ simd_size
= 8; S
&= 0x7; break;
839 case 0x38 ... 0x3b: /* 1110xx */ simd_size
= 4; S
&= 0x3; break;
840 case 0x3c ... 0x3d: /* 11110x */ simd_size
= 2; S
&= 0x1; break;
841 default: return FALSE
;
843 mask
= (1ull << simd_size
) - 1;
844 /* Top bits are IGNORED. */
848 if (simd_size
> esize
* 8)
851 /* NOTE: if S = simd_size - 1 we get 0xf..f which is rejected. */
852 if (S
== simd_size
- 1)
854 /* S+1 consecutive bits to 1. */
855 /* NOTE: S can't be 63 due to detection above. */
856 imm
= (1ull << (S
+ 1)) - 1;
857 /* Rotate to the left by simd_size - R. */
859 imm
= ((imm
<< (simd_size
- R
)) & mask
) | (imm
>> R
);
860 /* Replicate the value according to SIMD size. */
863 case 2: imm
= (imm
<< 2) | imm
;
865 case 4: imm
= (imm
<< 4) | imm
;
867 case 8: imm
= (imm
<< 8) | imm
;
869 case 16: imm
= (imm
<< 16) | imm
;
871 case 32: imm
= (imm
<< 32) | imm
;
874 default: assert (0); return 0;
877 *result
= imm
& ~((uint64_t) -1 << (esize
* 4) << (esize
* 4));
882 /* Decode a logical immediate for e.g. ORR <Wd|WSP>, <Wn>, #<imm>. */
884 aarch64_ext_limm (const aarch64_operand
*self
,
885 aarch64_opnd_info
*info
, const aarch64_insn code
,
886 const aarch64_inst
*inst
,
887 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
892 value
= extract_fields (code
, 0, 3, self
->fields
[0], self
->fields
[1],
894 esize
= aarch64_get_qualifier_esize (inst
->operands
[0].qualifier
);
895 return decode_limm (esize
, value
, &info
->imm
.value
);
898 /* Decode a logical immediate for the BIC alias of AND (etc.). */
900 aarch64_ext_inv_limm (const aarch64_operand
*self
,
901 aarch64_opnd_info
*info
, const aarch64_insn code
,
902 const aarch64_inst
*inst
,
903 aarch64_operand_error
*errors
)
905 if (!aarch64_ext_limm (self
, info
, code
, inst
, errors
))
907 info
->imm
.value
= ~info
->imm
.value
;
911 /* Decode Ft for e.g. STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]
912 or LDP <Qt1>, <Qt2>, [<Xn|SP>], #<imm>. */
914 aarch64_ext_ft (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
915 aarch64_opnd_info
*info
,
916 const aarch64_insn code
, const aarch64_inst
*inst
,
917 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
922 info
->reg
.regno
= extract_field (FLD_Rt
, code
, 0);
925 value
= extract_field (FLD_ldst_size
, code
, 0);
926 if (inst
->opcode
->iclass
== ldstpair_indexed
927 || inst
->opcode
->iclass
== ldstnapair_offs
928 || inst
->opcode
->iclass
== ldstpair_off
929 || inst
->opcode
->iclass
== loadlit
)
931 enum aarch64_opnd_qualifier qualifier
;
934 case 0: qualifier
= AARCH64_OPND_QLF_S_S
; break;
935 case 1: qualifier
= AARCH64_OPND_QLF_S_D
; break;
936 case 2: qualifier
= AARCH64_OPND_QLF_S_Q
; break;
937 default: return FALSE
;
939 info
->qualifier
= qualifier
;
944 value
= extract_fields (code
, 0, 2, FLD_opc1
, FLD_ldst_size
);
947 info
->qualifier
= get_sreg_qualifier_from_value (value
);
953 /* Decode the address operand for e.g. STXRB <Ws>, <Wt>, [<Xn|SP>{,#0}]. */
955 aarch64_ext_addr_simple (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
956 aarch64_opnd_info
*info
,
958 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
959 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
962 info
->addr
.base_regno
= extract_field (FLD_Rn
, code
, 0);
966 /* Decode the address operand for e.g.
967 stlur <Xt>, [<Xn|SP>{, <amount>}]. */
969 aarch64_ext_addr_offset (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
970 aarch64_opnd_info
*info
,
971 aarch64_insn code
, const aarch64_inst
*inst
,
972 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
974 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
977 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
980 aarch64_insn imm
= extract_fields (code
, 0, 1, self
->fields
[1]);
981 info
->addr
.offset
.imm
= sign_extend (imm
, 8);
982 if (extract_field (self
->fields
[2], code
, 0) == 1) {
983 info
->addr
.writeback
= 1;
984 info
->addr
.preind
= 1;
989 /* Decode the address operand for e.g.
990 STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]. */
992 aarch64_ext_addr_regoff (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
993 aarch64_opnd_info
*info
,
994 aarch64_insn code
, const aarch64_inst
*inst
,
995 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
997 aarch64_insn S
, value
;
1000 info
->addr
.base_regno
= extract_field (FLD_Rn
, code
, 0);
1002 info
->addr
.offset
.regno
= extract_field (FLD_Rm
, code
, 0);
1004 value
= extract_field (FLD_option
, code
, 0);
1005 info
->shifter
.kind
=
1006 aarch64_get_operand_modifier_from_value (value
, TRUE
/* extend_p */);
1007 /* Fix-up the shifter kind; although the table-driven approach is
1008 efficient, it is slightly inflexible, thus needing this fix-up. */
1009 if (info
->shifter
.kind
== AARCH64_MOD_UXTX
)
1010 info
->shifter
.kind
= AARCH64_MOD_LSL
;
1012 S
= extract_field (FLD_S
, code
, 0);
1015 info
->shifter
.amount
= 0;
1016 info
->shifter
.amount_present
= 0;
1021 /* Need information in other operand(s) to help achieve the decoding
1023 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
1024 /* Get the size of the data element that is accessed, which may be
1025 different from that of the source register size, e.g. in strb/ldrb. */
1026 size
= aarch64_get_qualifier_esize (info
->qualifier
);
1027 info
->shifter
.amount
= get_logsz (size
);
1028 info
->shifter
.amount_present
= 1;
1034 /* Decode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>], #<simm>. */
1036 aarch64_ext_addr_simm (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
1037 aarch64_insn code
, const aarch64_inst
*inst
,
1038 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1041 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
1044 info
->addr
.base_regno
= extract_field (FLD_Rn
, code
, 0);
1045 /* simm (imm9 or imm7) */
1046 imm
= extract_field (self
->fields
[0], code
, 0);
1047 info
->addr
.offset
.imm
= sign_extend (imm
, fields
[self
->fields
[0]].width
- 1);
1048 if (self
->fields
[0] == FLD_imm7
)
1049 /* scaled immediate in ld/st pair instructions. */
1050 info
->addr
.offset
.imm
*= aarch64_get_qualifier_esize (info
->qualifier
);
1052 if (inst
->opcode
->iclass
== ldst_unscaled
1053 || inst
->opcode
->iclass
== ldstnapair_offs
1054 || inst
->opcode
->iclass
== ldstpair_off
1055 || inst
->opcode
->iclass
== ldst_unpriv
)
1056 info
->addr
.writeback
= 0;
1059 /* pre/post- index */
1060 info
->addr
.writeback
= 1;
1061 if (extract_field (self
->fields
[1], code
, 0) == 1)
1062 info
->addr
.preind
= 1;
1064 info
->addr
.postind
= 1;
1070 /* Decode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>{, #<simm>}]. */
1072 aarch64_ext_addr_uimm12 (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
1074 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1075 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1078 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
1079 shift
= get_logsz (aarch64_get_qualifier_esize (info
->qualifier
));
1081 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1083 info
->addr
.offset
.imm
= extract_field (self
->fields
[1], code
, 0) << shift
;
1087 /* Decode the address operand for e.g. LDRAA <Xt>, [<Xn|SP>{, #<simm>}]. */
1089 aarch64_ext_addr_simm10 (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
1091 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1092 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1096 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
1098 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1100 imm
= extract_fields (code
, 0, 2, self
->fields
[1], self
->fields
[2]);
1101 info
->addr
.offset
.imm
= sign_extend (imm
, 9) << 3;
1102 if (extract_field (self
->fields
[3], code
, 0) == 1) {
1103 info
->addr
.writeback
= 1;
1104 info
->addr
.preind
= 1;
1109 /* Decode the address operand for e.g.
1110 LD1 {<Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>}, [<Xn|SP>], <Xm|#<amount>>. */
1112 aarch64_ext_simd_addr_post (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1113 aarch64_opnd_info
*info
,
1114 aarch64_insn code
, const aarch64_inst
*inst
,
1115 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1117 /* The opcode dependent area stores the number of elements in
1118 each structure to be loaded/stored. */
1119 int is_ld1r
= get_opcode_dependent_value (inst
->opcode
) == 1;
1122 info
->addr
.base_regno
= extract_field (FLD_Rn
, code
, 0);
1123 /* Rm | #<amount> */
1124 info
->addr
.offset
.regno
= extract_field (FLD_Rm
, code
, 0);
1125 if (info
->addr
.offset
.regno
== 31)
1127 if (inst
->opcode
->operands
[0] == AARCH64_OPND_LVt_AL
)
1128 /* Special handling of loading single structure to all lane. */
1129 info
->addr
.offset
.imm
= (is_ld1r
? 1
1130 : inst
->operands
[0].reglist
.num_regs
)
1131 * aarch64_get_qualifier_esize (inst
->operands
[0].qualifier
);
1133 info
->addr
.offset
.imm
= inst
->operands
[0].reglist
.num_regs
1134 * aarch64_get_qualifier_esize (inst
->operands
[0].qualifier
)
1135 * aarch64_get_qualifier_nelem (inst
->operands
[0].qualifier
);
1138 info
->addr
.offset
.is_reg
= 1;
1139 info
->addr
.writeback
= 1;
1144 /* Decode the condition operand for e.g. CSEL <Xd>, <Xn>, <Xm>, <cond>. */
1146 aarch64_ext_cond (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1147 aarch64_opnd_info
*info
,
1148 aarch64_insn code
, const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1149 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1153 value
= extract_field (FLD_cond
, code
, 0);
1154 info
->cond
= get_cond_from_value (value
);
1158 /* Decode the system register operand for e.g. MRS <Xt>, <systemreg>. */
1160 aarch64_ext_sysreg (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1161 aarch64_opnd_info
*info
,
1163 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1164 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1166 /* op0:op1:CRn:CRm:op2 */
1167 info
->sysreg
.value
= extract_fields (code
, 0, 5, FLD_op0
, FLD_op1
, FLD_CRn
,
1172 /* Decode the PSTATE field operand for e.g. MSR <pstatefield>, #<imm>. */
1174 aarch64_ext_pstatefield (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1175 aarch64_opnd_info
*info
, aarch64_insn code
,
1176 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1177 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1181 info
->pstatefield
= extract_fields (code
, 0, 2, FLD_op1
, FLD_op2
);
1182 for (i
= 0; aarch64_pstatefields
[i
].name
!= NULL
; ++i
)
1183 if (aarch64_pstatefields
[i
].value
== (aarch64_insn
)info
->pstatefield
)
1185 /* Reserved value in <pstatefield>. */
1189 /* Decode the system instruction op operand for e.g. AT <at_op>, <Xt>. */
1191 aarch64_ext_sysins_op (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1192 aarch64_opnd_info
*info
,
1194 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1195 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1199 const aarch64_sys_ins_reg
*sysins_ops
;
1200 /* op0:op1:CRn:CRm:op2 */
1201 value
= extract_fields (code
, 0, 5,
1202 FLD_op0
, FLD_op1
, FLD_CRn
,
1207 case AARCH64_OPND_SYSREG_AT
: sysins_ops
= aarch64_sys_regs_at
; break;
1208 case AARCH64_OPND_SYSREG_DC
: sysins_ops
= aarch64_sys_regs_dc
; break;
1209 case AARCH64_OPND_SYSREG_IC
: sysins_ops
= aarch64_sys_regs_ic
; break;
1210 case AARCH64_OPND_SYSREG_TLBI
: sysins_ops
= aarch64_sys_regs_tlbi
; break;
1211 default: assert (0); return FALSE
;
1214 for (i
= 0; sysins_ops
[i
].name
!= NULL
; ++i
)
1215 if (sysins_ops
[i
].value
== value
)
1217 info
->sysins_op
= sysins_ops
+ i
;
1218 DEBUG_TRACE ("%s found value: %x, has_xt: %d, i: %d.",
1219 info
->sysins_op
->name
,
1220 (unsigned)info
->sysins_op
->value
,
1221 aarch64_sys_ins_reg_has_xt (info
->sysins_op
), i
);
1228 /* Decode the memory barrier option operand for e.g. DMB <option>|#<imm>. */
1231 aarch64_ext_barrier (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1232 aarch64_opnd_info
*info
,
1234 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1235 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1238 info
->barrier
= aarch64_barrier_options
+ extract_field (FLD_CRm
, code
, 0);
1242 /* Decode the prefetch operation option operand for e.g.
1243 PRFM <prfop>, [<Xn|SP>{, #<pimm>}]. */
1246 aarch64_ext_prfop (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1247 aarch64_opnd_info
*info
,
1248 aarch64_insn code
, const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1249 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1252 info
->prfop
= aarch64_prfops
+ extract_field (FLD_Rt
, code
, 0);
1256 /* Decode the hint number for an alias taking an operand. Set info->hint_option
1257 to the matching name/value pair in aarch64_hint_options. */
1260 aarch64_ext_hint (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1261 aarch64_opnd_info
*info
,
1263 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1264 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1267 unsigned hint_number
;
1270 hint_number
= extract_fields (code
, 0, 2, FLD_CRm
, FLD_op2
);
1272 for (i
= 0; aarch64_hint_options
[i
].name
!= NULL
; i
++)
1274 if (hint_number
== aarch64_hint_options
[i
].value
)
1276 info
->hint_option
= &(aarch64_hint_options
[i
]);
1284 /* Decode the extended register operand for e.g.
1285 STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]. */
1287 aarch64_ext_reg_extended (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1288 aarch64_opnd_info
*info
,
1290 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1291 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1296 info
->reg
.regno
= extract_field (FLD_Rm
, code
, 0);
1298 value
= extract_field (FLD_option
, code
, 0);
1299 info
->shifter
.kind
=
1300 aarch64_get_operand_modifier_from_value (value
, TRUE
/* extend_p */);
1302 info
->shifter
.amount
= extract_field (FLD_imm3
, code
, 0);
1304 /* This makes the constraint checking happy. */
1305 info
->shifter
.operator_present
= 1;
1307 /* Assume inst->operands[0].qualifier has been resolved. */
1308 assert (inst
->operands
[0].qualifier
!= AARCH64_OPND_QLF_NIL
);
1309 info
->qualifier
= AARCH64_OPND_QLF_W
;
1310 if (inst
->operands
[0].qualifier
== AARCH64_OPND_QLF_X
1311 && (info
->shifter
.kind
== AARCH64_MOD_UXTX
1312 || info
->shifter
.kind
== AARCH64_MOD_SXTX
))
1313 info
->qualifier
= AARCH64_OPND_QLF_X
;
1318 /* Decode the shifted register operand for e.g.
1319 SUBS <Xd>, <Xn>, <Xm> {, <shift> #<amount>}. */
1321 aarch64_ext_reg_shifted (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1322 aarch64_opnd_info
*info
,
1324 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1325 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1330 info
->reg
.regno
= extract_field (FLD_Rm
, code
, 0);
1332 value
= extract_field (FLD_shift
, code
, 0);
1333 info
->shifter
.kind
=
1334 aarch64_get_operand_modifier_from_value (value
, FALSE
/* extend_p */);
1335 if (info
->shifter
.kind
== AARCH64_MOD_ROR
1336 && inst
->opcode
->iclass
!= log_shift
)
1337 /* ROR is not available for the shifted register operand in arithmetic
1341 info
->shifter
.amount
= extract_field (FLD_imm6
, code
, 0);
1343 /* This makes the constraint checking happy. */
1344 info
->shifter
.operator_present
= 1;
1349 /* Decode an SVE address [<base>, #<offset>*<factor>, MUL VL],
1350 where <offset> is given by the OFFSET parameter and where <factor> is
1351 1 plus SELF's operand-dependent value. fields[0] specifies the field
1352 that holds <base>. */
1354 aarch64_ext_sve_addr_reg_mul_vl (const aarch64_operand
*self
,
1355 aarch64_opnd_info
*info
, aarch64_insn code
,
1358 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1359 info
->addr
.offset
.imm
= offset
* (1 + get_operand_specific_data (self
));
1360 info
->addr
.offset
.is_reg
= FALSE
;
1361 info
->addr
.writeback
= FALSE
;
1362 info
->addr
.preind
= TRUE
;
1364 info
->shifter
.kind
= AARCH64_MOD_MUL_VL
;
1365 info
->shifter
.amount
= 1;
1366 info
->shifter
.operator_present
= (info
->addr
.offset
.imm
!= 0);
1367 info
->shifter
.amount_present
= FALSE
;
1371 /* Decode an SVE address [<base>, #<simm4>*<factor>, MUL VL],
1372 where <simm4> is a 4-bit signed value and where <factor> is 1 plus
1373 SELF's operand-dependent value. fields[0] specifies the field that
1374 holds <base>. <simm4> is encoded in the SVE_imm4 field. */
1376 aarch64_ext_sve_addr_ri_s4xvl (const aarch64_operand
*self
,
1377 aarch64_opnd_info
*info
, aarch64_insn code
,
1378 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1379 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1383 offset
= extract_field (FLD_SVE_imm4
, code
, 0);
1384 offset
= ((offset
+ 8) & 15) - 8;
1385 return aarch64_ext_sve_addr_reg_mul_vl (self
, info
, code
, offset
);
1388 /* Decode an SVE address [<base>, #<simm6>*<factor>, MUL VL],
1389 where <simm6> is a 6-bit signed value and where <factor> is 1 plus
1390 SELF's operand-dependent value. fields[0] specifies the field that
1391 holds <base>. <simm6> is encoded in the SVE_imm6 field. */
1393 aarch64_ext_sve_addr_ri_s6xvl (const aarch64_operand
*self
,
1394 aarch64_opnd_info
*info
, aarch64_insn code
,
1395 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1396 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1400 offset
= extract_field (FLD_SVE_imm6
, code
, 0);
1401 offset
= (((offset
+ 32) & 63) - 32);
1402 return aarch64_ext_sve_addr_reg_mul_vl (self
, info
, code
, offset
);
1405 /* Decode an SVE address [<base>, #<simm9>*<factor>, MUL VL],
1406 where <simm9> is a 9-bit signed value and where <factor> is 1 plus
1407 SELF's operand-dependent value. fields[0] specifies the field that
1408 holds <base>. <simm9> is encoded in the concatenation of the SVE_imm6
1409 and imm3 fields, with imm3 being the less-significant part. */
1411 aarch64_ext_sve_addr_ri_s9xvl (const aarch64_operand
*self
,
1412 aarch64_opnd_info
*info
,
1414 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1415 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1419 offset
= extract_fields (code
, 0, 2, FLD_SVE_imm6
, FLD_imm3
);
1420 offset
= (((offset
+ 256) & 511) - 256);
1421 return aarch64_ext_sve_addr_reg_mul_vl (self
, info
, code
, offset
);
1424 /* Decode an SVE address [<base>, #<offset> << <shift>], where <offset>
1425 is given by the OFFSET parameter and where <shift> is SELF's operand-
1426 dependent value. fields[0] specifies the base register field <base>. */
1428 aarch64_ext_sve_addr_reg_imm (const aarch64_operand
*self
,
1429 aarch64_opnd_info
*info
, aarch64_insn code
,
1432 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1433 info
->addr
.offset
.imm
= offset
* (1 << get_operand_specific_data (self
));
1434 info
->addr
.offset
.is_reg
= FALSE
;
1435 info
->addr
.writeback
= FALSE
;
1436 info
->addr
.preind
= TRUE
;
1437 info
->shifter
.operator_present
= FALSE
;
1438 info
->shifter
.amount_present
= FALSE
;
1442 /* Decode an SVE address [X<n>, #<SVE_imm4> << <shift>], where <SVE_imm4>
1443 is a 4-bit signed number and where <shift> is SELF's operand-dependent
1444 value. fields[0] specifies the base register field. */
1446 aarch64_ext_sve_addr_ri_s4 (const aarch64_operand
*self
,
1447 aarch64_opnd_info
*info
, aarch64_insn code
,
1448 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1449 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1451 int offset
= sign_extend (extract_field (FLD_SVE_imm4
, code
, 0), 3);
1452 return aarch64_ext_sve_addr_reg_imm (self
, info
, code
, offset
);
1455 /* Decode an SVE address [X<n>, #<SVE_imm6> << <shift>], where <SVE_imm6>
1456 is a 6-bit unsigned number and where <shift> is SELF's operand-dependent
1457 value. fields[0] specifies the base register field. */
1459 aarch64_ext_sve_addr_ri_u6 (const aarch64_operand
*self
,
1460 aarch64_opnd_info
*info
, aarch64_insn code
,
1461 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1462 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1464 int offset
= extract_field (FLD_SVE_imm6
, code
, 0);
1465 return aarch64_ext_sve_addr_reg_imm (self
, info
, code
, offset
);
1468 /* Decode an SVE address [X<n>, X<m>{, LSL #<shift>}], where <shift>
1469 is SELF's operand-dependent value. fields[0] specifies the base
1470 register field and fields[1] specifies the offset register field. */
1472 aarch64_ext_sve_addr_rr_lsl (const aarch64_operand
*self
,
1473 aarch64_opnd_info
*info
, aarch64_insn code
,
1474 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1475 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1479 index_regno
= extract_field (self
->fields
[1], code
, 0);
1480 if (index_regno
== 31 && (self
->flags
& OPD_F_NO_ZR
) != 0)
1483 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1484 info
->addr
.offset
.regno
= index_regno
;
1485 info
->addr
.offset
.is_reg
= TRUE
;
1486 info
->addr
.writeback
= FALSE
;
1487 info
->addr
.preind
= TRUE
;
1488 info
->shifter
.kind
= AARCH64_MOD_LSL
;
1489 info
->shifter
.amount
= get_operand_specific_data (self
);
1490 info
->shifter
.operator_present
= (info
->shifter
.amount
!= 0);
1491 info
->shifter
.amount_present
= (info
->shifter
.amount
!= 0);
1495 /* Decode an SVE address [X<n>, Z<m>.<T>, (S|U)XTW {#<shift>}], where
1496 <shift> is SELF's operand-dependent value. fields[0] specifies the
1497 base register field, fields[1] specifies the offset register field and
1498 fields[2] is a single-bit field that selects SXTW over UXTW. */
1500 aarch64_ext_sve_addr_rz_xtw (const aarch64_operand
*self
,
1501 aarch64_opnd_info
*info
, aarch64_insn code
,
1502 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1503 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1505 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1506 info
->addr
.offset
.regno
= extract_field (self
->fields
[1], code
, 0);
1507 info
->addr
.offset
.is_reg
= TRUE
;
1508 info
->addr
.writeback
= FALSE
;
1509 info
->addr
.preind
= TRUE
;
1510 if (extract_field (self
->fields
[2], code
, 0))
1511 info
->shifter
.kind
= AARCH64_MOD_SXTW
;
1513 info
->shifter
.kind
= AARCH64_MOD_UXTW
;
1514 info
->shifter
.amount
= get_operand_specific_data (self
);
1515 info
->shifter
.operator_present
= TRUE
;
1516 info
->shifter
.amount_present
= (info
->shifter
.amount
!= 0);
1520 /* Decode an SVE address [Z<n>.<T>, #<imm5> << <shift>], where <imm5> is a
1521 5-bit unsigned number and where <shift> is SELF's operand-dependent value.
1522 fields[0] specifies the base register field. */
1524 aarch64_ext_sve_addr_zi_u5 (const aarch64_operand
*self
,
1525 aarch64_opnd_info
*info
, aarch64_insn code
,
1526 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1527 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1529 int offset
= extract_field (FLD_imm5
, code
, 0);
1530 return aarch64_ext_sve_addr_reg_imm (self
, info
, code
, offset
);
1533 /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>{, <modifier> {#<msz>}}],
1534 where <modifier> is given by KIND and where <msz> is a 2-bit unsigned
1535 number. fields[0] specifies the base register field and fields[1]
1536 specifies the offset register field. */
1538 aarch64_ext_sve_addr_zz (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
1539 aarch64_insn code
, enum aarch64_modifier_kind kind
)
1541 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
1542 info
->addr
.offset
.regno
= extract_field (self
->fields
[1], code
, 0);
1543 info
->addr
.offset
.is_reg
= TRUE
;
1544 info
->addr
.writeback
= FALSE
;
1545 info
->addr
.preind
= TRUE
;
1546 info
->shifter
.kind
= kind
;
1547 info
->shifter
.amount
= extract_field (FLD_SVE_msz
, code
, 0);
1548 info
->shifter
.operator_present
= (kind
!= AARCH64_MOD_LSL
1549 || info
->shifter
.amount
!= 0);
1550 info
->shifter
.amount_present
= (info
->shifter
.amount
!= 0);
1554 /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>{, LSL #<msz>}], where
1555 <msz> is a 2-bit unsigned number. fields[0] specifies the base register
1556 field and fields[1] specifies the offset register field. */
1558 aarch64_ext_sve_addr_zz_lsl (const aarch64_operand
*self
,
1559 aarch64_opnd_info
*info
, aarch64_insn code
,
1560 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1561 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1563 return aarch64_ext_sve_addr_zz (self
, info
, code
, AARCH64_MOD_LSL
);
1566 /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>, SXTW {#<msz>}], where
1567 <msz> is a 2-bit unsigned number. fields[0] specifies the base register
1568 field and fields[1] specifies the offset register field. */
1570 aarch64_ext_sve_addr_zz_sxtw (const aarch64_operand
*self
,
1571 aarch64_opnd_info
*info
, aarch64_insn code
,
1572 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1573 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1575 return aarch64_ext_sve_addr_zz (self
, info
, code
, AARCH64_MOD_SXTW
);
1578 /* Decode an SVE address [Z<n>.<T>, Z<m>.<T>, UXTW {#<msz>}], where
1579 <msz> is a 2-bit unsigned number. fields[0] specifies the base register
1580 field and fields[1] specifies the offset register field. */
1582 aarch64_ext_sve_addr_zz_uxtw (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 return aarch64_ext_sve_addr_zz (self
, info
, code
, AARCH64_MOD_UXTW
);
1590 /* Finish decoding an SVE arithmetic immediate, given that INFO already
1591 has the raw field value and that the low 8 bits decode to VALUE. */
1593 decode_sve_aimm (aarch64_opnd_info
*info
, int64_t value
)
1595 info
->shifter
.kind
= AARCH64_MOD_LSL
;
1596 info
->shifter
.amount
= 0;
1597 if (info
->imm
.value
& 0x100)
1600 /* Decode 0x100 as #0, LSL #8. */
1601 info
->shifter
.amount
= 8;
1605 info
->shifter
.operator_present
= (info
->shifter
.amount
!= 0);
1606 info
->shifter
.amount_present
= (info
->shifter
.amount
!= 0);
1607 info
->imm
.value
= value
;
1611 /* Decode an SVE ADD/SUB immediate. */
1613 aarch64_ext_sve_aimm (const aarch64_operand
*self
,
1614 aarch64_opnd_info
*info
, const aarch64_insn code
,
1615 const aarch64_inst
*inst
,
1616 aarch64_operand_error
*errors
)
1618 return (aarch64_ext_imm (self
, info
, code
, inst
, errors
)
1619 && decode_sve_aimm (info
, (uint8_t) info
->imm
.value
));
1622 /* Decode an SVE CPY/DUP immediate. */
1624 aarch64_ext_sve_asimm (const aarch64_operand
*self
,
1625 aarch64_opnd_info
*info
, const aarch64_insn code
,
1626 const aarch64_inst
*inst
,
1627 aarch64_operand_error
*errors
)
1629 return (aarch64_ext_imm (self
, info
, code
, inst
, errors
)
1630 && decode_sve_aimm (info
, (int8_t) info
->imm
.value
));
1633 /* Decode a single-bit immediate that selects between #0.5 and #1.0.
1634 The fields array specifies which field to use. */
1636 aarch64_ext_sve_float_half_one (const aarch64_operand
*self
,
1637 aarch64_opnd_info
*info
, aarch64_insn code
,
1638 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1639 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1641 if (extract_field (self
->fields
[0], code
, 0))
1642 info
->imm
.value
= 0x3f800000;
1644 info
->imm
.value
= 0x3f000000;
1645 info
->imm
.is_fp
= TRUE
;
1649 /* Decode a single-bit immediate that selects between #0.5 and #2.0.
1650 The fields array specifies which field to use. */
1652 aarch64_ext_sve_float_half_two (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 if (extract_field (self
->fields
[0], code
, 0))
1658 info
->imm
.value
= 0x40000000;
1660 info
->imm
.value
= 0x3f000000;
1661 info
->imm
.is_fp
= TRUE
;
1665 /* Decode a single-bit immediate that selects between #0.0 and #1.0.
1666 The fields array specifies which field to use. */
1668 aarch64_ext_sve_float_zero_one (const aarch64_operand
*self
,
1669 aarch64_opnd_info
*info
, aarch64_insn code
,
1670 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1671 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1673 if (extract_field (self
->fields
[0], code
, 0))
1674 info
->imm
.value
= 0x3f800000;
1676 info
->imm
.value
= 0x0;
1677 info
->imm
.is_fp
= TRUE
;
1681 /* Decode Zn[MM], where MM has a 7-bit triangular encoding. The fields
1682 array specifies which field to use for Zn. MM is encoded in the
1683 concatenation of imm5 and SVE_tszh, with imm5 being the less
1684 significant part. */
1686 aarch64_ext_sve_index (const aarch64_operand
*self
,
1687 aarch64_opnd_info
*info
, aarch64_insn code
,
1688 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1689 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1693 info
->reglane
.regno
= extract_field (self
->fields
[0], code
, 0);
1694 val
= extract_fields (code
, 0, 2, FLD_SVE_tszh
, FLD_imm5
);
1695 if ((val
& 31) == 0)
1697 while ((val
& 1) == 0)
1699 info
->reglane
.index
= val
/ 2;
1703 /* Decode a logical immediate for the MOV alias of SVE DUPM. */
1705 aarch64_ext_sve_limm_mov (const aarch64_operand
*self
,
1706 aarch64_opnd_info
*info
, const aarch64_insn code
,
1707 const aarch64_inst
*inst
,
1708 aarch64_operand_error
*errors
)
1710 int esize
= aarch64_get_qualifier_esize (inst
->operands
[0].qualifier
);
1711 return (aarch64_ext_limm (self
, info
, code
, inst
, errors
)
1712 && aarch64_sve_dupm_mov_immediate_p (info
->imm
.value
, esize
));
1715 /* Decode Zn[MM], where Zn occupies the least-significant part of the field
1716 and where MM occupies the most-significant part. The operand-dependent
1717 value specifies the number of bits in Zn. */
1719 aarch64_ext_sve_quad_index (const aarch64_operand
*self
,
1720 aarch64_opnd_info
*info
, aarch64_insn code
,
1721 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1722 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1724 unsigned int reg_bits
= get_operand_specific_data (self
);
1725 unsigned int val
= extract_all_fields (self
, code
);
1726 info
->reglane
.regno
= val
& ((1 << reg_bits
) - 1);
1727 info
->reglane
.index
= val
>> reg_bits
;
1731 /* Decode {Zn.<T> - Zm.<T>}. The fields array specifies which field
1732 to use for Zn. The opcode-dependent value specifies the number
1733 of registers in the list. */
1735 aarch64_ext_sve_reglist (const aarch64_operand
*self
,
1736 aarch64_opnd_info
*info
, aarch64_insn code
,
1737 const aarch64_inst
*inst ATTRIBUTE_UNUSED
,
1738 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
1740 info
->reglist
.first_regno
= extract_field (self
->fields
[0], code
, 0);
1741 info
->reglist
.num_regs
= get_opcode_dependent_value (inst
->opcode
);
1745 /* Decode <pattern>{, MUL #<amount>}. The fields array specifies which
1746 fields to use for <pattern>. <amount> - 1 is encoded in the SVE_imm4
1749 aarch64_ext_sve_scale (const aarch64_operand
*self
,
1750 aarch64_opnd_info
*info
, aarch64_insn code
,
1751 const aarch64_inst
*inst
, aarch64_operand_error
*errors
)
1755 if (!aarch64_ext_imm (self
, info
, code
, inst
, errors
))
1757 val
= extract_field (FLD_SVE_imm4
, code
, 0);
1758 info
->shifter
.kind
= AARCH64_MOD_MUL
;
1759 info
->shifter
.amount
= val
+ 1;
1760 info
->shifter
.operator_present
= (val
!= 0);
1761 info
->shifter
.amount_present
= (val
!= 0);
1765 /* Return the top set bit in VALUE, which is expected to be relatively
1768 get_top_bit (uint64_t value
)
1770 while ((value
& -value
) != value
)
1771 value
-= value
& -value
;
1775 /* Decode an SVE shift-left immediate. */
1777 aarch64_ext_sve_shlimm (const aarch64_operand
*self
,
1778 aarch64_opnd_info
*info
, const aarch64_insn code
,
1779 const aarch64_inst
*inst
, aarch64_operand_error
*errors
)
1781 if (!aarch64_ext_imm (self
, info
, code
, inst
, errors
)
1782 || info
->imm
.value
== 0)
1785 info
->imm
.value
-= get_top_bit (info
->imm
.value
);
1789 /* Decode an SVE shift-right immediate. */
1791 aarch64_ext_sve_shrimm (const aarch64_operand
*self
,
1792 aarch64_opnd_info
*info
, const aarch64_insn code
,
1793 const aarch64_inst
*inst
, aarch64_operand_error
*errors
)
1795 if (!aarch64_ext_imm (self
, info
, code
, inst
, errors
)
1796 || info
->imm
.value
== 0)
1799 info
->imm
.value
= get_top_bit (info
->imm
.value
) * 2 - info
->imm
.value
;
1803 /* Bitfields that are commonly used to encode certain operands' information
1804 may be partially used as part of the base opcode in some instructions.
1805 For example, the bit 1 of the field 'size' in
1806 FCVTXN <Vb><d>, <Va><n>
1807 is actually part of the base opcode, while only size<0> is available
1808 for encoding the register type. Another example is the AdvSIMD
1809 instruction ORR (register), in which the field 'size' is also used for
1810 the base opcode, leaving only the field 'Q' available to encode the
1811 vector register arrangement specifier '8B' or '16B'.
1813 This function tries to deduce the qualifier from the value of partially
1814 constrained field(s). Given the VALUE of such a field or fields, the
1815 qualifiers CANDIDATES and the MASK (indicating which bits are valid for
1816 operand encoding), the function returns the matching qualifier or
1817 AARCH64_OPND_QLF_NIL if nothing matches.
1819 N.B. CANDIDATES is a group of possible qualifiers that are valid for
1820 one operand; it has a maximum of AARCH64_MAX_QLF_SEQ_NUM qualifiers and
1821 may end with AARCH64_OPND_QLF_NIL. */
1823 static enum aarch64_opnd_qualifier
1824 get_qualifier_from_partial_encoding (aarch64_insn value
,
1825 const enum aarch64_opnd_qualifier
* \
1830 DEBUG_TRACE ("enter with value: %d, mask: %d", (int)value
, (int)mask
);
1831 for (i
= 0; i
< AARCH64_MAX_QLF_SEQ_NUM
; ++i
)
1833 aarch64_insn standard_value
;
1834 if (candidates
[i
] == AARCH64_OPND_QLF_NIL
)
1836 standard_value
= aarch64_get_qualifier_standard_value (candidates
[i
]);
1837 if ((standard_value
& mask
) == (value
& mask
))
1838 return candidates
[i
];
1840 return AARCH64_OPND_QLF_NIL
;
1843 /* Given a list of qualifier sequences, return all possible valid qualifiers
1844 for operand IDX in QUALIFIERS.
1845 Assume QUALIFIERS is an array whose length is large enough. */
1848 get_operand_possible_qualifiers (int idx
,
1849 const aarch64_opnd_qualifier_seq_t
*list
,
1850 enum aarch64_opnd_qualifier
*qualifiers
)
1853 for (i
= 0; i
< AARCH64_MAX_QLF_SEQ_NUM
; ++i
)
1854 if ((qualifiers
[i
] = list
[i
][idx
]) == AARCH64_OPND_QLF_NIL
)
1858 /* Decode the size Q field for e.g. SHADD.
1859 We tag one operand with the qualifer according to the code;
1860 whether the qualifier is valid for this opcode or not, it is the
1861 duty of the semantic checking. */
1864 decode_sizeq (aarch64_inst
*inst
)
1867 enum aarch64_opnd_qualifier qualifier
;
1869 aarch64_insn value
, mask
;
1870 enum aarch64_field_kind fld_sz
;
1871 enum aarch64_opnd_qualifier candidates
[AARCH64_MAX_QLF_SEQ_NUM
];
1873 if (inst
->opcode
->iclass
== asisdlse
1874 || inst
->opcode
->iclass
== asisdlsep
1875 || inst
->opcode
->iclass
== asisdlso
1876 || inst
->opcode
->iclass
== asisdlsop
)
1877 fld_sz
= FLD_vldst_size
;
1882 value
= extract_fields (code
, inst
->opcode
->mask
, 2, fld_sz
, FLD_Q
);
1883 /* Obtain the info that which bits of fields Q and size are actually
1884 available for operand encoding. Opcodes like FMAXNM and FMLA have
1885 size[1] unavailable. */
1886 mask
= extract_fields (~inst
->opcode
->mask
, 0, 2, fld_sz
, FLD_Q
);
1888 /* The index of the operand we are going to tag a qualifier and the qualifer
1889 itself are reasoned from the value of the size and Q fields and the
1890 possible valid qualifier lists. */
1891 idx
= aarch64_select_operand_for_sizeq_field_coding (inst
->opcode
);
1892 DEBUG_TRACE ("key idx: %d", idx
);
1894 /* For most related instruciton, size:Q are fully available for operand
1898 inst
->operands
[idx
].qualifier
= get_vreg_qualifier_from_value (value
);
1902 get_operand_possible_qualifiers (idx
, inst
->opcode
->qualifiers_list
,
1904 #ifdef DEBUG_AARCH64
1908 for (i
= 0; candidates
[i
] != AARCH64_OPND_QLF_NIL
1909 && i
< AARCH64_MAX_QLF_SEQ_NUM
; ++i
)
1910 DEBUG_TRACE ("qualifier %d: %s", i
,
1911 aarch64_get_qualifier_name(candidates
[i
]));
1912 DEBUG_TRACE ("%d, %d", (int)value
, (int)mask
);
1914 #endif /* DEBUG_AARCH64 */
1916 qualifier
= get_qualifier_from_partial_encoding (value
, candidates
, mask
);
1918 if (qualifier
== AARCH64_OPND_QLF_NIL
)
1921 inst
->operands
[idx
].qualifier
= qualifier
;
1925 /* Decode size[0]:Q, i.e. bit 22 and bit 30, for
1926 e.g. FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>. */
1929 decode_asimd_fcvt (aarch64_inst
*inst
)
1931 aarch64_field field
= {0, 0};
1933 enum aarch64_opnd_qualifier qualifier
;
1935 gen_sub_field (FLD_size
, 0, 1, &field
);
1936 value
= extract_field_2 (&field
, inst
->value
, 0);
1937 qualifier
= value
== 0 ? AARCH64_OPND_QLF_V_4S
1938 : AARCH64_OPND_QLF_V_2D
;
1939 switch (inst
->opcode
->op
)
1943 /* FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>. */
1944 inst
->operands
[1].qualifier
= qualifier
;
1948 /* FCVTL<Q> <Vd>.<Ta>, <Vn>.<Tb>. */
1949 inst
->operands
[0].qualifier
= qualifier
;
1959 /* Decode size[0], i.e. bit 22, for
1960 e.g. FCVTXN <Vb><d>, <Va><n>. */
1963 decode_asisd_fcvtxn (aarch64_inst
*inst
)
1965 aarch64_field field
= {0, 0};
1966 gen_sub_field (FLD_size
, 0, 1, &field
);
1967 if (!extract_field_2 (&field
, inst
->value
, 0))
1969 inst
->operands
[0].qualifier
= AARCH64_OPND_QLF_S_S
;
1973 /* Decode the 'opc' field for e.g. FCVT <Dd>, <Sn>. */
1975 decode_fcvt (aarch64_inst
*inst
)
1977 enum aarch64_opnd_qualifier qualifier
;
1979 const aarch64_field field
= {15, 2};
1982 value
= extract_field_2 (&field
, inst
->value
, 0);
1985 case 0: qualifier
= AARCH64_OPND_QLF_S_S
; break;
1986 case 1: qualifier
= AARCH64_OPND_QLF_S_D
; break;
1987 case 3: qualifier
= AARCH64_OPND_QLF_S_H
; break;
1990 inst
->operands
[0].qualifier
= qualifier
;
1995 /* Do miscellaneous decodings that are not common enough to be driven by
1999 do_misc_decoding (aarch64_inst
*inst
)
2002 switch (inst
->opcode
->op
)
2005 return decode_fcvt (inst
);
2011 return decode_asimd_fcvt (inst
);
2014 return decode_asisd_fcvtxn (inst
);
2018 value
= extract_field (FLD_SVE_Pn
, inst
->value
, 0);
2019 return (value
== extract_field (FLD_SVE_Pm
, inst
->value
, 0)
2020 && value
== extract_field (FLD_SVE_Pg4_10
, inst
->value
, 0));
2023 return (extract_field (FLD_SVE_Zd
, inst
->value
, 0)
2024 == extract_field (FLD_SVE_Zm_16
, inst
->value
, 0));
2027 /* Index must be zero. */
2028 value
= extract_fields (inst
->value
, 0, 2, FLD_SVE_tszh
, FLD_imm5
);
2029 return value
> 0 && value
<= 16 && value
== (value
& -value
);
2032 return (extract_field (FLD_SVE_Zn
, inst
->value
, 0)
2033 == extract_field (FLD_SVE_Zm_16
, inst
->value
, 0));
2036 /* Index must be nonzero. */
2037 value
= extract_fields (inst
->value
, 0, 2, FLD_SVE_tszh
, FLD_imm5
);
2038 return value
> 0 && value
!= (value
& -value
);
2041 return (extract_field (FLD_SVE_Pd
, inst
->value
, 0)
2042 == extract_field (FLD_SVE_Pm
, inst
->value
, 0));
2044 case OP_MOVZS_P_P_P
:
2046 return (extract_field (FLD_SVE_Pn
, inst
->value
, 0)
2047 == extract_field (FLD_SVE_Pm
, inst
->value
, 0));
2049 case OP_NOTS_P_P_P_Z
:
2050 case OP_NOT_P_P_P_Z
:
2051 return (extract_field (FLD_SVE_Pm
, inst
->value
, 0)
2052 == extract_field (FLD_SVE_Pg4_10
, inst
->value
, 0));
2059 /* Opcodes that have fields shared by multiple operands are usually flagged
2060 with flags. In this function, we detect such flags, decode the related
2061 field(s) and store the information in one of the related operands. The
2062 'one' operand is not any operand but one of the operands that can
2063 accommadate all the information that has been decoded. */
2066 do_special_decoding (aarch64_inst
*inst
)
2070 /* Condition for truly conditional executed instructions, e.g. b.cond. */
2071 if (inst
->opcode
->flags
& F_COND
)
2073 value
= extract_field (FLD_cond2
, inst
->value
, 0);
2074 inst
->cond
= get_cond_from_value (value
);
2077 if (inst
->opcode
->flags
& F_SF
)
2079 idx
= select_operand_for_sf_field_coding (inst
->opcode
);
2080 value
= extract_field (FLD_sf
, inst
->value
, 0);
2081 inst
->operands
[idx
].qualifier
= get_greg_qualifier_from_value (value
);
2082 if ((inst
->opcode
->flags
& F_N
)
2083 && extract_field (FLD_N
, inst
->value
, 0) != value
)
2087 if (inst
->opcode
->flags
& F_LSE_SZ
)
2089 idx
= select_operand_for_sf_field_coding (inst
->opcode
);
2090 value
= extract_field (FLD_lse_sz
, inst
->value
, 0);
2091 inst
->operands
[idx
].qualifier
= get_greg_qualifier_from_value (value
);
2093 /* size:Q fields. */
2094 if (inst
->opcode
->flags
& F_SIZEQ
)
2095 return decode_sizeq (inst
);
2097 if (inst
->opcode
->flags
& F_FPTYPE
)
2099 idx
= select_operand_for_fptype_field_coding (inst
->opcode
);
2100 value
= extract_field (FLD_type
, inst
->value
, 0);
2103 case 0: inst
->operands
[idx
].qualifier
= AARCH64_OPND_QLF_S_S
; break;
2104 case 1: inst
->operands
[idx
].qualifier
= AARCH64_OPND_QLF_S_D
; break;
2105 case 3: inst
->operands
[idx
].qualifier
= AARCH64_OPND_QLF_S_H
; break;
2110 if (inst
->opcode
->flags
& F_SSIZE
)
2112 /* N.B. some opcodes like FCMGT <V><d>, <V><n>, #0 have the size[1] as part
2113 of the base opcode. */
2115 enum aarch64_opnd_qualifier candidates
[AARCH64_MAX_QLF_SEQ_NUM
];
2116 idx
= select_operand_for_scalar_size_field_coding (inst
->opcode
);
2117 value
= extract_field (FLD_size
, inst
->value
, inst
->opcode
->mask
);
2118 mask
= extract_field (FLD_size
, ~inst
->opcode
->mask
, 0);
2119 /* For most related instruciton, the 'size' field is fully available for
2120 operand encoding. */
2122 inst
->operands
[idx
].qualifier
= get_sreg_qualifier_from_value (value
);
2125 get_operand_possible_qualifiers (idx
, inst
->opcode
->qualifiers_list
,
2127 inst
->operands
[idx
].qualifier
2128 = get_qualifier_from_partial_encoding (value
, candidates
, mask
);
2132 if (inst
->opcode
->flags
& F_T
)
2134 /* Num of consecutive '0's on the right side of imm5<3:0>. */
2137 assert (aarch64_get_operand_class (inst
->opcode
->operands
[0])
2138 == AARCH64_OPND_CLASS_SIMD_REG
);
2149 val
= extract_field (FLD_imm5
, inst
->value
, 0);
2150 while ((val
& 0x1) == 0 && ++num
<= 3)
2154 Q
= (unsigned) extract_field (FLD_Q
, inst
->value
, inst
->opcode
->mask
);
2155 inst
->operands
[0].qualifier
=
2156 get_vreg_qualifier_from_value ((num
<< 1) | Q
);
2159 if (inst
->opcode
->flags
& F_GPRSIZE_IN_Q
)
2161 /* Use Rt to encode in the case of e.g.
2162 STXP <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}]. */
2163 idx
= aarch64_operand_index (inst
->opcode
->operands
, AARCH64_OPND_Rt
);
2166 /* Otherwise use the result operand, which has to be a integer
2168 assert (aarch64_get_operand_class (inst
->opcode
->operands
[0])
2169 == AARCH64_OPND_CLASS_INT_REG
);
2172 assert (idx
== 0 || idx
== 1);
2173 value
= extract_field (FLD_Q
, inst
->value
, 0);
2174 inst
->operands
[idx
].qualifier
= get_greg_qualifier_from_value (value
);
2177 if (inst
->opcode
->flags
& F_LDS_SIZE
)
2179 aarch64_field field
= {0, 0};
2180 assert (aarch64_get_operand_class (inst
->opcode
->operands
[0])
2181 == AARCH64_OPND_CLASS_INT_REG
);
2182 gen_sub_field (FLD_opc
, 0, 1, &field
);
2183 value
= extract_field_2 (&field
, inst
->value
, 0);
2184 inst
->operands
[0].qualifier
2185 = value
? AARCH64_OPND_QLF_W
: AARCH64_OPND_QLF_X
;
2188 /* Miscellaneous decoding; done as the last step. */
2189 if (inst
->opcode
->flags
& F_MISC
)
2190 return do_misc_decoding (inst
);
2195 /* Converters converting a real opcode instruction to its alias form. */
2197 /* ROR <Wd>, <Ws>, #<shift>
2199 EXTR <Wd>, <Ws>, <Ws>, #<shift>. */
2201 convert_extr_to_ror (aarch64_inst
*inst
)
2203 if (inst
->operands
[1].reg
.regno
== inst
->operands
[2].reg
.regno
)
2205 copy_operand_info (inst
, 2, 3);
2206 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
2212 /* UXTL<Q> <Vd>.<Ta>, <Vn>.<Tb>
2214 USHLL<Q> <Vd>.<Ta>, <Vn>.<Tb>, #0. */
2216 convert_shll_to_xtl (aarch64_inst
*inst
)
2218 if (inst
->operands
[2].imm
.value
== 0)
2220 inst
->operands
[2].type
= AARCH64_OPND_NIL
;
2227 UBFM <Xd>, <Xn>, #<shift>, #63.
2229 LSR <Xd>, <Xn>, #<shift>. */
2231 convert_bfm_to_sr (aarch64_inst
*inst
)
2235 imms
= inst
->operands
[3].imm
.value
;
2236 val
= inst
->operands
[2].qualifier
== AARCH64_OPND_QLF_imm_0_31
? 31 : 63;
2239 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
2246 /* Convert MOV to ORR. */
2248 convert_orr_to_mov (aarch64_inst
*inst
)
2250 /* MOV <Vd>.<T>, <Vn>.<T>
2252 ORR <Vd>.<T>, <Vn>.<T>, <Vn>.<T>. */
2253 if (inst
->operands
[1].reg
.regno
== inst
->operands
[2].reg
.regno
)
2255 inst
->operands
[2].type
= AARCH64_OPND_NIL
;
2261 /* When <imms> >= <immr>, the instruction written:
2262 SBFX <Xd>, <Xn>, #<lsb>, #<width>
2264 SBFM <Xd>, <Xn>, #<lsb>, #(<lsb>+<width>-1). */
2267 convert_bfm_to_bfx (aarch64_inst
*inst
)
2271 immr
= inst
->operands
[2].imm
.value
;
2272 imms
= inst
->operands
[3].imm
.value
;
2276 inst
->operands
[2].imm
.value
= lsb
;
2277 inst
->operands
[3].imm
.value
= imms
+ 1 - lsb
;
2278 /* The two opcodes have different qualifiers for
2279 the immediate operands; reset to help the checking. */
2280 reset_operand_qualifier (inst
, 2);
2281 reset_operand_qualifier (inst
, 3);
2288 /* When <imms> < <immr>, the instruction written:
2289 SBFIZ <Xd>, <Xn>, #<lsb>, #<width>
2291 SBFM <Xd>, <Xn>, #((64-<lsb>)&0x3f), #(<width>-1). */
2294 convert_bfm_to_bfi (aarch64_inst
*inst
)
2296 int64_t immr
, imms
, val
;
2298 immr
= inst
->operands
[2].imm
.value
;
2299 imms
= inst
->operands
[3].imm
.value
;
2300 val
= inst
->operands
[2].qualifier
== AARCH64_OPND_QLF_imm_0_31
? 32 : 64;
2303 inst
->operands
[2].imm
.value
= (val
- immr
) & (val
- 1);
2304 inst
->operands
[3].imm
.value
= imms
+ 1;
2305 /* The two opcodes have different qualifiers for
2306 the immediate operands; reset to help the checking. */
2307 reset_operand_qualifier (inst
, 2);
2308 reset_operand_qualifier (inst
, 3);
2315 /* The instruction written:
2316 BFC <Xd>, #<lsb>, #<width>
2318 BFM <Xd>, XZR, #((64-<lsb>)&0x3f), #(<width>-1). */
2321 convert_bfm_to_bfc (aarch64_inst
*inst
)
2323 int64_t immr
, imms
, val
;
2325 /* Should have been assured by the base opcode value. */
2326 assert (inst
->operands
[1].reg
.regno
== 0x1f);
2328 immr
= inst
->operands
[2].imm
.value
;
2329 imms
= inst
->operands
[3].imm
.value
;
2330 val
= inst
->operands
[2].qualifier
== AARCH64_OPND_QLF_imm_0_31
? 32 : 64;
2333 /* Drop XZR from the second operand. */
2334 copy_operand_info (inst
, 1, 2);
2335 copy_operand_info (inst
, 2, 3);
2336 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
2338 /* Recalculate the immediates. */
2339 inst
->operands
[1].imm
.value
= (val
- immr
) & (val
- 1);
2340 inst
->operands
[2].imm
.value
= imms
+ 1;
2342 /* The two opcodes have different qualifiers for the operands; reset to
2343 help the checking. */
2344 reset_operand_qualifier (inst
, 1);
2345 reset_operand_qualifier (inst
, 2);
2346 reset_operand_qualifier (inst
, 3);
2354 /* The instruction written:
2355 LSL <Xd>, <Xn>, #<shift>
2357 UBFM <Xd>, <Xn>, #((64-<shift>)&0x3f), #(63-<shift>). */
2360 convert_ubfm_to_lsl (aarch64_inst
*inst
)
2362 int64_t immr
= inst
->operands
[2].imm
.value
;
2363 int64_t imms
= inst
->operands
[3].imm
.value
;
2365 = inst
->operands
[2].qualifier
== AARCH64_OPND_QLF_imm_0_31
? 31 : 63;
2367 if ((immr
== 0 && imms
== val
) || immr
== imms
+ 1)
2369 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
2370 inst
->operands
[2].imm
.value
= val
- imms
;
2377 /* CINC <Wd>, <Wn>, <cond>
2379 CSINC <Wd>, <Wn>, <Wn>, invert(<cond>)
2380 where <cond> is not AL or NV. */
2383 convert_from_csel (aarch64_inst
*inst
)
2385 if (inst
->operands
[1].reg
.regno
== inst
->operands
[2].reg
.regno
2386 && (inst
->operands
[3].cond
->value
& 0xe) != 0xe)
2388 copy_operand_info (inst
, 2, 3);
2389 inst
->operands
[2].cond
= get_inverted_cond (inst
->operands
[3].cond
);
2390 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
2396 /* CSET <Wd>, <cond>
2398 CSINC <Wd>, WZR, WZR, invert(<cond>)
2399 where <cond> is not AL or NV. */
2402 convert_csinc_to_cset (aarch64_inst
*inst
)
2404 if (inst
->operands
[1].reg
.regno
== 0x1f
2405 && inst
->operands
[2].reg
.regno
== 0x1f
2406 && (inst
->operands
[3].cond
->value
& 0xe) != 0xe)
2408 copy_operand_info (inst
, 1, 3);
2409 inst
->operands
[1].cond
= get_inverted_cond (inst
->operands
[3].cond
);
2410 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
2411 inst
->operands
[2].type
= AARCH64_OPND_NIL
;
2419 MOVZ <Wd>, #<imm16>, LSL #<shift>.
2421 A disassembler may output ORR, MOVZ and MOVN as a MOV mnemonic, except when
2422 ORR has an immediate that could be generated by a MOVZ or MOVN instruction,
2423 or where a MOVN has an immediate that could be encoded by MOVZ, or where
2424 MOVZ/MOVN #0 have a shift amount other than LSL #0, in which case the
2425 machine-instruction mnemonic must be used. */
2428 convert_movewide_to_mov (aarch64_inst
*inst
)
2430 uint64_t value
= inst
->operands
[1].imm
.value
;
2431 /* MOVZ/MOVN #0 have a shift amount other than LSL #0. */
2432 if (value
== 0 && inst
->operands
[1].shifter
.amount
!= 0)
2434 inst
->operands
[1].type
= AARCH64_OPND_IMM_MOV
;
2435 inst
->operands
[1].shifter
.kind
= AARCH64_MOD_NONE
;
2436 value
<<= inst
->operands
[1].shifter
.amount
;
2437 /* As an alias convertor, it has to be clear that the INST->OPCODE
2438 is the opcode of the real instruction. */
2439 if (inst
->opcode
->op
== OP_MOVN
)
2441 int is32
= inst
->operands
[0].qualifier
== AARCH64_OPND_QLF_W
;
2443 /* A MOVN has an immediate that could be encoded by MOVZ. */
2444 if (aarch64_wide_constant_p (value
, is32
, NULL
))
2447 inst
->operands
[1].imm
.value
= value
;
2448 inst
->operands
[1].shifter
.amount
= 0;
2454 ORR <Wd>, WZR, #<imm>.
2456 A disassembler may output ORR, MOVZ and MOVN as a MOV mnemonic, except when
2457 ORR has an immediate that could be generated by a MOVZ or MOVN instruction,
2458 or where a MOVN has an immediate that could be encoded by MOVZ, or where
2459 MOVZ/MOVN #0 have a shift amount other than LSL #0, in which case the
2460 machine-instruction mnemonic must be used. */
2463 convert_movebitmask_to_mov (aarch64_inst
*inst
)
2468 /* Should have been assured by the base opcode value. */
2469 assert (inst
->operands
[1].reg
.regno
== 0x1f);
2470 copy_operand_info (inst
, 1, 2);
2471 is32
= inst
->operands
[0].qualifier
== AARCH64_OPND_QLF_W
;
2472 inst
->operands
[1].type
= AARCH64_OPND_IMM_MOV
;
2473 value
= inst
->operands
[1].imm
.value
;
2474 /* ORR has an immediate that could be generated by a MOVZ or MOVN
2476 if (inst
->operands
[0].reg
.regno
!= 0x1f
2477 && (aarch64_wide_constant_p (value
, is32
, NULL
)
2478 || aarch64_wide_constant_p (~value
, is32
, NULL
)))
2481 inst
->operands
[2].type
= AARCH64_OPND_NIL
;
2485 /* Some alias opcodes are disassembled by being converted from their real-form.
2486 N.B. INST->OPCODE is the real opcode rather than the alias. */
2489 convert_to_alias (aarch64_inst
*inst
, const aarch64_opcode
*alias
)
2495 return convert_bfm_to_sr (inst
);
2497 return convert_ubfm_to_lsl (inst
);
2501 return convert_from_csel (inst
);
2504 return convert_csinc_to_cset (inst
);
2508 return convert_bfm_to_bfx (inst
);
2512 return convert_bfm_to_bfi (inst
);
2514 return convert_bfm_to_bfc (inst
);
2516 return convert_orr_to_mov (inst
);
2517 case OP_MOV_IMM_WIDE
:
2518 case OP_MOV_IMM_WIDEN
:
2519 return convert_movewide_to_mov (inst
);
2520 case OP_MOV_IMM_LOG
:
2521 return convert_movebitmask_to_mov (inst
);
2523 return convert_extr_to_ror (inst
);
2528 return convert_shll_to_xtl (inst
);
2535 aarch64_opcode_decode (const aarch64_opcode
*, const aarch64_insn
,
2536 aarch64_inst
*, int, aarch64_operand_error
*errors
);
2538 /* Given the instruction information in *INST, check if the instruction has
2539 any alias form that can be used to represent *INST. If the answer is yes,
2540 update *INST to be in the form of the determined alias. */
2542 /* In the opcode description table, the following flags are used in opcode
2543 entries to help establish the relations between the real and alias opcodes:
2545 F_ALIAS: opcode is an alias
2546 F_HAS_ALIAS: opcode has alias(es)
2549 F_P3: Disassembly preference priority 1-3 (the larger the
2550 higher). If nothing is specified, it is the priority
2551 0 by default, i.e. the lowest priority.
2553 Although the relation between the machine and the alias instructions are not
2554 explicitly described, it can be easily determined from the base opcode
2555 values, masks and the flags F_ALIAS and F_HAS_ALIAS in their opcode
2556 description entries:
2558 The mask of an alias opcode must be equal to or a super-set (i.e. more
2559 constrained) of that of the aliased opcode; so is the base opcode value.
2561 if (opcode_has_alias (real) && alias_opcode_p (opcode)
2562 && (opcode->mask & real->mask) == real->mask
2563 && (real->mask & opcode->opcode) == (real->mask & real->opcode))
2564 then OPCODE is an alias of, and only of, the REAL instruction
2566 The alias relationship is forced flat-structured to keep related algorithm
2567 simple; an opcode entry cannot be flagged with both F_ALIAS and F_HAS_ALIAS.
2569 During the disassembling, the decoding decision tree (in
2570 opcodes/aarch64-dis-2.c) always returns an machine instruction opcode entry;
2571 if the decoding of such a machine instruction succeeds (and -Mno-aliases is
2572 not specified), the disassembler will check whether there is any alias
2573 instruction exists for this real instruction. If there is, the disassembler
2574 will try to disassemble the 32-bit binary again using the alias's rule, or
2575 try to convert the IR to the form of the alias. In the case of the multiple
2576 aliases, the aliases are tried one by one from the highest priority
2577 (currently the flag F_P3) to the lowest priority (no priority flag), and the
2578 first succeeds first adopted.
2580 You may ask why there is a need for the conversion of IR from one form to
2581 another in handling certain aliases. This is because on one hand it avoids
2582 adding more operand code to handle unusual encoding/decoding; on other
2583 hand, during the disassembling, the conversion is an effective approach to
2584 check the condition of an alias (as an alias may be adopted only if certain
2585 conditions are met).
2587 In order to speed up the alias opcode lookup, aarch64-gen has preprocessed
2588 aarch64_opcode_table and generated aarch64_find_alias_opcode and
2589 aarch64_find_next_alias_opcode (in opcodes/aarch64-dis-2.c) to help. */
2592 determine_disassembling_preference (struct aarch64_inst
*inst
,
2593 aarch64_operand_error
*errors
)
2595 const aarch64_opcode
*opcode
;
2596 const aarch64_opcode
*alias
;
2598 opcode
= inst
->opcode
;
2600 /* This opcode does not have an alias, so use itself. */
2601 if (!opcode_has_alias (opcode
))
2604 alias
= aarch64_find_alias_opcode (opcode
);
2607 #ifdef DEBUG_AARCH64
2610 const aarch64_opcode
*tmp
= alias
;
2611 printf ("#### LIST orderd: ");
2614 printf ("%s, ", tmp
->name
);
2615 tmp
= aarch64_find_next_alias_opcode (tmp
);
2619 #endif /* DEBUG_AARCH64 */
2621 for (; alias
; alias
= aarch64_find_next_alias_opcode (alias
))
2623 DEBUG_TRACE ("try %s", alias
->name
);
2624 assert (alias_opcode_p (alias
) || opcode_has_alias (opcode
));
2626 /* An alias can be a pseudo opcode which will never be used in the
2627 disassembly, e.g. BIC logical immediate is such a pseudo opcode
2629 if (pseudo_opcode_p (alias
))
2631 DEBUG_TRACE ("skip pseudo %s", alias
->name
);
2635 if ((inst
->value
& alias
->mask
) != alias
->opcode
)
2637 DEBUG_TRACE ("skip %s as base opcode not match", alias
->name
);
2640 /* No need to do any complicated transformation on operands, if the alias
2641 opcode does not have any operand. */
2642 if (aarch64_num_of_operands (alias
) == 0 && alias
->opcode
== inst
->value
)
2644 DEBUG_TRACE ("succeed with 0-operand opcode %s", alias
->name
);
2645 aarch64_replace_opcode (inst
, alias
);
2648 if (alias
->flags
& F_CONV
)
2651 memcpy (©
, inst
, sizeof (aarch64_inst
));
2652 /* ALIAS is the preference as long as the instruction can be
2653 successfully converted to the form of ALIAS. */
2654 if (convert_to_alias (©
, alias
) == 1)
2656 aarch64_replace_opcode (©
, alias
);
2657 assert (aarch64_match_operands_constraint (©
, NULL
));
2658 DEBUG_TRACE ("succeed with %s via conversion", alias
->name
);
2659 memcpy (inst
, ©
, sizeof (aarch64_inst
));
2665 /* Directly decode the alias opcode. */
2667 memset (&temp
, '\0', sizeof (aarch64_inst
));
2668 if (aarch64_opcode_decode (alias
, inst
->value
, &temp
, 1, errors
) == 1)
2670 DEBUG_TRACE ("succeed with %s via direct decoding", alias
->name
);
2671 memcpy (inst
, &temp
, sizeof (aarch64_inst
));
2678 /* Some instructions (including all SVE ones) use the instruction class
2679 to describe how a qualifiers_list index is represented in the instruction
2680 encoding. If INST is such an instruction, decode the appropriate fields
2681 and fill in the operand qualifiers accordingly. Return true if no
2682 problems are found. */
2685 aarch64_decode_variant_using_iclass (aarch64_inst
*inst
)
2690 switch (inst
->opcode
->iclass
)
2693 variant
= extract_fields (inst
->value
, 0, 2, FLD_size
, FLD_SVE_M_14
);
2697 i
= extract_fields (inst
->value
, 0, 2, FLD_SVE_tszh
, FLD_imm5
);
2700 while ((i
& 1) == 0)
2708 /* Pick the smallest applicable element size. */
2709 if ((inst
->value
& 0x20600) == 0x600)
2711 else if ((inst
->value
& 0x20400) == 0x400)
2713 else if ((inst
->value
& 0x20000) == 0)
2720 /* sve_misc instructions have only a single variant. */
2724 variant
= extract_fields (inst
->value
, 0, 2, FLD_size
, FLD_SVE_M_16
);
2728 variant
= extract_field (FLD_SVE_M_4
, inst
->value
, 0);
2731 case sve_shift_pred
:
2732 i
= extract_fields (inst
->value
, 0, 2, FLD_SVE_tszh
, FLD_SVE_tszl_8
);
2743 case sve_shift_unpred
:
2744 i
= extract_fields (inst
->value
, 0, 2, FLD_SVE_tszh
, FLD_SVE_tszl_19
);
2748 variant
= extract_field (FLD_size
, inst
->value
, 0);
2754 variant
= extract_field (FLD_size
, inst
->value
, 0);
2758 i
= extract_field (FLD_size
, inst
->value
, 0);
2765 variant
= extract_field (FLD_SVE_sz
, inst
->value
, 0);
2769 /* No mapping between instruction class and qualifiers. */
2773 for (i
= 0; i
< AARCH64_MAX_OPND_NUM
; ++i
)
2774 inst
->operands
[i
].qualifier
= inst
->opcode
->qualifiers_list
[variant
][i
];
2777 /* Decode the CODE according to OPCODE; fill INST. Return 0 if the decoding
2778 fails, which meanes that CODE is not an instruction of OPCODE; otherwise
2781 If OPCODE has alias(es) and NOALIASES_P is 0, an alias opcode may be
2782 determined and used to disassemble CODE; this is done just before the
2786 aarch64_opcode_decode (const aarch64_opcode
*opcode
, const aarch64_insn code
,
2787 aarch64_inst
*inst
, int noaliases_p
,
2788 aarch64_operand_error
*errors
)
2792 DEBUG_TRACE ("enter with %s", opcode
->name
);
2794 assert (opcode
&& inst
);
2797 memset (inst
, '\0', sizeof (aarch64_inst
));
2799 /* Check the base opcode. */
2800 if ((code
& opcode
->mask
) != (opcode
->opcode
& opcode
->mask
))
2802 DEBUG_TRACE ("base opcode match FAIL");
2806 inst
->opcode
= opcode
;
2809 /* Assign operand codes and indexes. */
2810 for (i
= 0; i
< AARCH64_MAX_OPND_NUM
; ++i
)
2812 if (opcode
->operands
[i
] == AARCH64_OPND_NIL
)
2814 inst
->operands
[i
].type
= opcode
->operands
[i
];
2815 inst
->operands
[i
].idx
= i
;
2818 /* Call the opcode decoder indicated by flags. */
2819 if (opcode_has_special_coder (opcode
) && do_special_decoding (inst
) == 0)
2821 DEBUG_TRACE ("opcode flag-based decoder FAIL");
2825 /* Possibly use the instruction class to determine the correct
2827 if (!aarch64_decode_variant_using_iclass (inst
))
2829 DEBUG_TRACE ("iclass-based decoder FAIL");
2833 /* Call operand decoders. */
2834 for (i
= 0; i
< AARCH64_MAX_OPND_NUM
; ++i
)
2836 const aarch64_operand
*opnd
;
2837 enum aarch64_opnd type
;
2839 type
= opcode
->operands
[i
];
2840 if (type
== AARCH64_OPND_NIL
)
2842 opnd
= &aarch64_operands
[type
];
2843 if (operand_has_extractor (opnd
)
2844 && (! aarch64_extract_operand (opnd
, &inst
->operands
[i
], code
, inst
,
2847 DEBUG_TRACE ("operand decoder FAIL at operand %d", i
);
2852 /* If the opcode has a verifier, then check it now. */
2853 if (opcode
->verifier
&& ! opcode
->verifier (opcode
, code
))
2855 DEBUG_TRACE ("operand verifier FAIL");
2859 /* Match the qualifiers. */
2860 if (aarch64_match_operands_constraint (inst
, NULL
) == 1)
2862 /* Arriving here, the CODE has been determined as a valid instruction
2863 of OPCODE and *INST has been filled with information of this OPCODE
2864 instruction. Before the return, check if the instruction has any
2865 alias and should be disassembled in the form of its alias instead.
2866 If the answer is yes, *INST will be updated. */
2868 determine_disassembling_preference (inst
, errors
);
2869 DEBUG_TRACE ("SUCCESS");
2874 DEBUG_TRACE ("constraint matching FAIL");
2881 /* This does some user-friendly fix-up to *INST. It is currently focus on
2882 the adjustment of qualifiers to help the printed instruction
2883 recognized/understood more easily. */
2886 user_friendly_fixup (aarch64_inst
*inst
)
2888 switch (inst
->opcode
->iclass
)
2891 /* TBNZ Xn|Wn, #uimm6, label
2892 Test and Branch Not Zero: conditionally jumps to label if bit number
2893 uimm6 in register Xn is not zero. The bit number implies the width of
2894 the register, which may be written and should be disassembled as Wn if
2895 uimm is less than 32. Limited to a branch offset range of +/- 32KiB.
2897 if (inst
->operands
[1].imm
.value
< 32)
2898 inst
->operands
[0].qualifier
= AARCH64_OPND_QLF_W
;
2904 /* Decode INSN and fill in *INST the instruction information. An alias
2905 opcode may be filled in *INSN if NOALIASES_P is FALSE. Return zero on
2909 aarch64_decode_insn (aarch64_insn insn
, aarch64_inst
*inst
,
2910 bfd_boolean noaliases_p
,
2911 aarch64_operand_error
*errors
)
2913 const aarch64_opcode
*opcode
= aarch64_opcode_lookup (insn
);
2915 #ifdef DEBUG_AARCH64
2918 const aarch64_opcode
*tmp
= opcode
;
2920 DEBUG_TRACE ("opcode lookup:");
2923 aarch64_verbose (" %s", tmp
->name
);
2924 tmp
= aarch64_find_next_opcode (tmp
);
2927 #endif /* DEBUG_AARCH64 */
2929 /* A list of opcodes may have been found, as aarch64_opcode_lookup cannot
2930 distinguish some opcodes, e.g. SSHR and MOVI, which almost share the same
2931 opcode field and value, apart from the difference that one of them has an
2932 extra field as part of the opcode, but such a field is used for operand
2933 encoding in other opcode(s) ('immh' in the case of the example). */
2934 while (opcode
!= NULL
)
2936 /* But only one opcode can be decoded successfully for, as the
2937 decoding routine will check the constraint carefully. */
2938 if (aarch64_opcode_decode (opcode
, insn
, inst
, noaliases_p
, errors
) == 1)
2940 opcode
= aarch64_find_next_opcode (opcode
);
2946 /* Print operands. */
2949 print_operands (bfd_vma pc
, const aarch64_opcode
*opcode
,
2950 const aarch64_opnd_info
*opnds
, struct disassemble_info
*info
)
2952 int i
, pcrel_p
, num_printed
;
2953 for (i
= 0, num_printed
= 0; i
< AARCH64_MAX_OPND_NUM
; ++i
)
2956 /* We regard the opcode operand info more, however we also look into
2957 the inst->operands to support the disassembling of the optional
2959 The two operand code should be the same in all cases, apart from
2960 when the operand can be optional. */
2961 if (opcode
->operands
[i
] == AARCH64_OPND_NIL
2962 || opnds
[i
].type
== AARCH64_OPND_NIL
)
2965 /* Generate the operand string in STR. */
2966 aarch64_print_operand (str
, sizeof (str
), pc
, opcode
, opnds
, i
, &pcrel_p
,
2969 /* Print the delimiter (taking account of omitted operand(s)). */
2971 (*info
->fprintf_func
) (info
->stream
, "%s",
2972 num_printed
++ == 0 ? "\t" : ", ");
2974 /* Print the operand. */
2976 (*info
->print_address_func
) (info
->target
, info
);
2978 (*info
->fprintf_func
) (info
->stream
, "%s", str
);
2982 /* Set NAME to a copy of INST's mnemonic with the "." suffix removed. */
2985 remove_dot_suffix (char *name
, const aarch64_inst
*inst
)
2990 ptr
= strchr (inst
->opcode
->name
, '.');
2991 assert (ptr
&& inst
->cond
);
2992 len
= ptr
- inst
->opcode
->name
;
2994 strncpy (name
, inst
->opcode
->name
, len
);
2998 /* Print the instruction mnemonic name. */
3001 print_mnemonic_name (const aarch64_inst
*inst
, struct disassemble_info
*info
)
3003 if (inst
->opcode
->flags
& F_COND
)
3005 /* For instructions that are truly conditionally executed, e.g. b.cond,
3006 prepare the full mnemonic name with the corresponding condition
3010 remove_dot_suffix (name
, inst
);
3011 (*info
->fprintf_func
) (info
->stream
, "%s.%s", name
, inst
->cond
->names
[0]);
3014 (*info
->fprintf_func
) (info
->stream
, "%s", inst
->opcode
->name
);
3017 /* Decide whether we need to print a comment after the operands of
3018 instruction INST. */
3021 print_comment (const aarch64_inst
*inst
, struct disassemble_info
*info
)
3023 if (inst
->opcode
->flags
& F_COND
)
3026 unsigned int i
, num_conds
;
3028 remove_dot_suffix (name
, inst
);
3029 num_conds
= ARRAY_SIZE (inst
->cond
->names
);
3030 for (i
= 1; i
< num_conds
&& inst
->cond
->names
[i
]; ++i
)
3031 (*info
->fprintf_func
) (info
->stream
, "%s %s.%s",
3032 i
== 1 ? " //" : ",",
3033 name
, inst
->cond
->names
[i
]);
3037 /* Print the instruction according to *INST. */
3040 print_aarch64_insn (bfd_vma pc
, const aarch64_inst
*inst
,
3041 struct disassemble_info
*info
)
3043 print_mnemonic_name (inst
, info
);
3044 print_operands (pc
, inst
->opcode
, inst
->operands
, info
);
3045 print_comment (inst
, info
);
3048 /* Entry-point of the instruction disassembler and printer. */
3051 print_insn_aarch64_word (bfd_vma pc
,
3053 struct disassemble_info
*info
,
3054 aarch64_operand_error
*errors
)
3056 static const char *err_msg
[6] =
3059 [-ERR_UND
] = "undefined",
3060 [-ERR_UNP
] = "unpredictable",
3067 info
->insn_info_valid
= 1;
3068 info
->branch_delay_insns
= 0;
3069 info
->data_size
= 0;
3073 if (info
->flags
& INSN_HAS_RELOC
)
3074 /* If the instruction has a reloc associated with it, then
3075 the offset field in the instruction will actually be the
3076 addend for the reloc. (If we are using REL type relocs).
3077 In such cases, we can ignore the pc when computing
3078 addresses, since the addend is not currently pc-relative. */
3081 ret
= aarch64_decode_insn (word
, &inst
, no_aliases
, errors
);
3083 if (((word
>> 21) & 0x3ff) == 1)
3085 /* RESERVED for ALES. */
3086 assert (ret
!= ERR_OK
);
3095 /* Handle undefined instructions. */
3096 info
->insn_type
= dis_noninsn
;
3097 (*info
->fprintf_func
) (info
->stream
,".inst\t0x%08x ; %s",
3098 word
, err_msg
[-ret
]);
3101 user_friendly_fixup (&inst
);
3102 print_aarch64_insn (pc
, &inst
, info
);
3109 /* Disallow mapping symbols ($x, $d etc) from
3110 being displayed in symbol relative addresses. */
3113 aarch64_symbol_is_valid (asymbol
* sym
,
3114 struct disassemble_info
* info ATTRIBUTE_UNUSED
)
3121 name
= bfd_asymbol_name (sym
);
3125 || (name
[1] != 'x' && name
[1] != 'd')
3126 || (name
[2] != '\0' && name
[2] != '.'));
3129 /* Print data bytes on INFO->STREAM. */
3132 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED
,
3134 struct disassemble_info
*info
,
3135 aarch64_operand_error
*errors ATTRIBUTE_UNUSED
)
3137 switch (info
->bytes_per_chunk
)
3140 info
->fprintf_func (info
->stream
, ".byte\t0x%02x", word
);
3143 info
->fprintf_func (info
->stream
, ".short\t0x%04x", word
);
3146 info
->fprintf_func (info
->stream
, ".word\t0x%08x", word
);
3153 /* Try to infer the code or data type from a symbol.
3154 Returns nonzero if *MAP_TYPE was set. */
3157 get_sym_code_type (struct disassemble_info
*info
, int n
,
3158 enum map_type
*map_type
)
3160 elf_symbol_type
*es
;
3164 /* If the symbol is in a different section, ignore it. */
3165 if (info
->section
!= NULL
&& info
->section
!= info
->symtab
[n
]->section
)
3168 es
= *(elf_symbol_type
**)(info
->symtab
+ n
);
3169 type
= ELF_ST_TYPE (es
->internal_elf_sym
.st_info
);
3171 /* If the symbol has function type then use that. */
3172 if (type
== STT_FUNC
)
3174 *map_type
= MAP_INSN
;
3178 /* Check for mapping symbols. */
3179 name
= bfd_asymbol_name(info
->symtab
[n
]);
3181 && (name
[1] == 'x' || name
[1] == 'd')
3182 && (name
[2] == '\0' || name
[2] == '.'))
3184 *map_type
= (name
[1] == 'x' ? MAP_INSN
: MAP_DATA
);
3191 /* Entry-point of the AArch64 disassembler. */
3194 print_insn_aarch64 (bfd_vma pc
,
3195 struct disassemble_info
*info
)
3197 bfd_byte buffer
[INSNLEN
];
3199 void (*printer
) (bfd_vma
, uint32_t, struct disassemble_info
*,
3200 aarch64_operand_error
*);
3201 bfd_boolean found
= FALSE
;
3202 unsigned int size
= 4;
3204 aarch64_operand_error errors
;
3206 if (info
->disassembler_options
)
3208 set_default_aarch64_dis_options (info
);
3210 parse_aarch64_dis_options (info
->disassembler_options
);
3212 /* To avoid repeated parsing of these options, we remove them here. */
3213 info
->disassembler_options
= NULL
;
3216 /* Aarch64 instructions are always little-endian */
3217 info
->endian_code
= BFD_ENDIAN_LITTLE
;
3219 /* First check the full symtab for a mapping symbol, even if there
3220 are no usable non-mapping symbols for this address. */
3221 if (info
->symtab_size
!= 0
3222 && bfd_asymbol_flavour (*info
->symtab
) == bfd_target_elf_flavour
)
3224 enum map_type type
= MAP_INSN
;
3229 if (pc
<= last_mapping_addr
)
3230 last_mapping_sym
= -1;
3232 /* Start scanning at the start of the function, or wherever
3233 we finished last time. */
3234 n
= info
->symtab_pos
+ 1;
3235 if (n
< last_mapping_sym
)
3236 n
= last_mapping_sym
;
3238 /* Scan up to the location being disassembled. */
3239 for (; n
< info
->symtab_size
; n
++)
3241 addr
= bfd_asymbol_value (info
->symtab
[n
]);
3244 if (get_sym_code_type (info
, n
, &type
))
3253 n
= info
->symtab_pos
;
3254 if (n
< last_mapping_sym
)
3255 n
= last_mapping_sym
;
3257 /* No mapping symbol found at this address. Look backwards
3258 for a preceeding one. */
3261 if (get_sym_code_type (info
, n
, &type
))
3270 last_mapping_sym
= last_sym
;
3273 /* Look a little bit ahead to see if we should print out
3274 less than four bytes of data. If there's a symbol,
3275 mapping or otherwise, after two bytes then don't
3277 if (last_type
== MAP_DATA
)
3279 size
= 4 - (pc
& 3);
3280 for (n
= last_sym
+ 1; n
< info
->symtab_size
; n
++)
3282 addr
= bfd_asymbol_value (info
->symtab
[n
]);
3285 if (addr
- pc
< size
)
3290 /* If the next symbol is after three bytes, we need to
3291 print only part of the data, so that we can use either
3294 size
= (pc
& 1) ? 1 : 2;
3298 if (last_type
== MAP_DATA
)
3300 /* size was set above. */
3301 info
->bytes_per_chunk
= size
;
3302 info
->display_endian
= info
->endian
;
3303 printer
= print_insn_data
;
3307 info
->bytes_per_chunk
= size
= INSNLEN
;
3308 info
->display_endian
= info
->endian_code
;
3309 printer
= print_insn_aarch64_word
;
3312 status
= (*info
->read_memory_func
) (pc
, buffer
, size
, info
);
3315 (*info
->memory_error_func
) (status
, pc
, info
);
3319 data
= bfd_get_bits (buffer
, size
* 8,
3320 info
->display_endian
== BFD_ENDIAN_BIG
);
3322 (*printer
) (pc
, data
, info
, &errors
);
3328 print_aarch64_disassembler_options (FILE *stream
)
3330 fprintf (stream
, _("\n\
3331 The following AARCH64 specific disassembler options are supported for use\n\
3332 with the -M switch (multiple options should be separated by commas):\n"));
3334 fprintf (stream
, _("\n\
3335 no-aliases Don't print instruction aliases.\n"));
3337 fprintf (stream
, _("\n\
3338 aliases Do print instruction aliases.\n"));
3340 #ifdef DEBUG_AARCH64
3341 fprintf (stream
, _("\n\
3342 debug_dump Temp switch for debug trace.\n"));
3343 #endif /* DEBUG_AARCH64 */
3345 fprintf (stream
, _("\n"));