1 /* aarch64-dis.c -- AArch64 disassembler.
2 Copyright (C) 2009-2016 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"
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 fprintf (stderr
, _("Unrecognised disassembler option: %s\n"), 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. */
126 static inline aarch64_insn
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
)
250 info
->reg
.regno
= extract_field (self
->fields
[0], code
, 0);
255 aarch64_ext_regno_pair (const aarch64_operand
*self ATTRIBUTE_UNUSED
, aarch64_opnd_info
*info
,
256 const aarch64_insn code ATTRIBUTE_UNUSED
,
257 const aarch64_inst
*inst ATTRIBUTE_UNUSED
)
259 assert (info
->idx
== 1
261 info
->reg
.regno
= inst
->operands
[info
->idx
- 1].reg
.regno
+ 1;
265 /* e.g. IC <ic_op>{, <Xt>}. */
267 aarch64_ext_regrt_sysins (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
268 const aarch64_insn code
,
269 const aarch64_inst
*inst ATTRIBUTE_UNUSED
)
271 info
->reg
.regno
= extract_field (self
->fields
[0], code
, 0);
272 assert (info
->idx
== 1
273 && (aarch64_get_operand_class (inst
->operands
[0].type
)
274 == AARCH64_OPND_CLASS_SYSTEM
));
275 /* This will make the constraint checking happy and more importantly will
276 help the disassembler determine whether this operand is optional or
278 info
->present
= aarch64_sys_ins_reg_has_xt (inst
->operands
[0].sysins_op
);
283 /* e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]. */
285 aarch64_ext_reglane (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
286 const aarch64_insn code
,
287 const aarch64_inst
*inst ATTRIBUTE_UNUSED
)
290 info
->reglane
.regno
= extract_field (self
->fields
[0], code
,
293 /* Index and/or type. */
294 if (inst
->opcode
->iclass
== asisdone
295 || inst
->opcode
->iclass
== asimdins
)
297 if (info
->type
== AARCH64_OPND_En
298 && inst
->opcode
->operands
[0] == AARCH64_OPND_Ed
)
301 /* index2 for e.g. INS <Vd>.<Ts>[<index1>], <Vn>.<Ts>[<index2>]. */
302 assert (info
->idx
== 1); /* Vn */
303 aarch64_insn value
= extract_field (FLD_imm4
, code
, 0);
304 /* Depend on AARCH64_OPND_Ed to determine the qualifier. */
305 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
306 shift
= get_logsz (aarch64_get_qualifier_esize (info
->qualifier
));
307 info
->reglane
.index
= value
>> shift
;
311 /* index and type for e.g. DUP <V><d>, <Vn>.<T>[<index>].
319 aarch64_insn value
= extract_field (FLD_imm5
, code
, 0);
320 while (++pos
<= 3 && (value
& 0x1) == 0)
324 info
->qualifier
= get_sreg_qualifier_from_value (pos
);
325 info
->reglane
.index
= (unsigned) (value
>> 1);
330 /* Index only for e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
331 or SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]. */
333 /* Need information in other operand(s) to help decoding. */
334 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
335 switch (info
->qualifier
)
337 case AARCH64_OPND_QLF_S_H
:
339 info
->reglane
.index
= extract_fields (code
, 0, 3, FLD_H
, FLD_L
,
341 info
->reglane
.regno
&= 0xf;
343 case AARCH64_OPND_QLF_S_S
:
345 info
->reglane
.index
= extract_fields (code
, 0, 2, FLD_H
, FLD_L
);
347 case AARCH64_OPND_QLF_S_D
:
349 info
->reglane
.index
= extract_field (FLD_H
, code
, 0);
360 aarch64_ext_reglist (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
361 const aarch64_insn code
,
362 const aarch64_inst
*inst ATTRIBUTE_UNUSED
)
365 info
->reglist
.first_regno
= extract_field (self
->fields
[0], code
, 0);
367 info
->reglist
.num_regs
= extract_field (FLD_len
, code
, 0) + 1;
371 /* Decode Rt and opcode fields of Vt in AdvSIMD load/store instructions. */
373 aarch64_ext_ldst_reglist (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
374 aarch64_opnd_info
*info
, const aarch64_insn code
,
375 const aarch64_inst
*inst
)
378 /* Number of elements in each structure to be loaded/stored. */
379 unsigned expected_num
= get_opcode_dependent_value (inst
->opcode
);
383 unsigned is_reserved
;
385 unsigned num_elements
;
401 info
->reglist
.first_regno
= extract_field (FLD_Rt
, code
, 0);
403 value
= extract_field (FLD_opcode
, code
, 0);
404 if (expected_num
!= data
[value
].num_elements
|| data
[value
].is_reserved
)
406 info
->reglist
.num_regs
= data
[value
].num_regs
;
411 /* Decode Rt and S fields of Vt in AdvSIMD load single structure to all
412 lanes instructions. */
414 aarch64_ext_ldst_reglist_r (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
415 aarch64_opnd_info
*info
, const aarch64_insn code
,
416 const aarch64_inst
*inst
)
421 info
->reglist
.first_regno
= extract_field (FLD_Rt
, code
, 0);
423 value
= extract_field (FLD_S
, code
, 0);
425 /* Number of registers is equal to the number of elements in
426 each structure to be loaded/stored. */
427 info
->reglist
.num_regs
= get_opcode_dependent_value (inst
->opcode
);
428 assert (info
->reglist
.num_regs
>= 1 && info
->reglist
.num_regs
<= 4);
430 /* Except when it is LD1R. */
431 if (info
->reglist
.num_regs
== 1 && value
== (aarch64_insn
) 1)
432 info
->reglist
.num_regs
= 2;
437 /* Decode Q, opcode<2:1>, S, size and Rt fields of Vt in AdvSIMD
438 load/store single element instructions. */
440 aarch64_ext_ldst_elemlist (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
441 aarch64_opnd_info
*info
, const aarch64_insn code
,
442 const aarch64_inst
*inst ATTRIBUTE_UNUSED
)
444 aarch64_field field
= {0, 0};
445 aarch64_insn QSsize
; /* fields Q:S:size. */
446 aarch64_insn opcodeh2
; /* opcode<2:1> */
449 info
->reglist
.first_regno
= extract_field (FLD_Rt
, code
, 0);
451 /* Decode the index, opcode<2:1> and size. */
452 gen_sub_field (FLD_asisdlso_opcode
, 1, 2, &field
);
453 opcodeh2
= extract_field_2 (&field
, code
, 0);
454 QSsize
= extract_fields (code
, 0, 3, FLD_Q
, FLD_S
, FLD_vldst_size
);
458 info
->qualifier
= AARCH64_OPND_QLF_S_B
;
459 /* Index encoded in "Q:S:size". */
460 info
->reglist
.index
= QSsize
;
466 info
->qualifier
= AARCH64_OPND_QLF_S_H
;
467 /* Index encoded in "Q:S:size<1>". */
468 info
->reglist
.index
= QSsize
>> 1;
471 if ((QSsize
>> 1) & 0x1)
474 if ((QSsize
& 0x1) == 0)
476 info
->qualifier
= AARCH64_OPND_QLF_S_S
;
477 /* Index encoded in "Q:S". */
478 info
->reglist
.index
= QSsize
>> 2;
482 if (extract_field (FLD_S
, code
, 0))
485 info
->qualifier
= AARCH64_OPND_QLF_S_D
;
486 /* Index encoded in "Q". */
487 info
->reglist
.index
= QSsize
>> 3;
494 info
->reglist
.has_index
= 1;
495 info
->reglist
.num_regs
= 0;
496 /* Number of registers is equal to the number of elements in
497 each structure to be loaded/stored. */
498 info
->reglist
.num_regs
= get_opcode_dependent_value (inst
->opcode
);
499 assert (info
->reglist
.num_regs
>= 1 && info
->reglist
.num_regs
<= 4);
504 /* Decode fields immh:immb and/or Q for e.g.
505 SSHR <Vd>.<T>, <Vn>.<T>, #<shift>
506 or SSHR <V><d>, <V><n>, #<shift>. */
509 aarch64_ext_advsimd_imm_shift (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
510 aarch64_opnd_info
*info
, const aarch64_insn code
,
511 const aarch64_inst
*inst
)
514 aarch64_insn Q
, imm
, immh
;
515 enum aarch64_insn_class iclass
= inst
->opcode
->iclass
;
517 immh
= extract_field (FLD_immh
, code
, 0);
520 imm
= extract_fields (code
, 0, 2, FLD_immh
, FLD_immb
);
522 /* Get highest set bit in immh. */
523 while (--pos
>= 0 && (immh
& 0x8) == 0)
526 assert ((iclass
== asimdshf
|| iclass
== asisdshf
)
527 && (info
->type
== AARCH64_OPND_IMM_VLSR
528 || info
->type
== AARCH64_OPND_IMM_VLSL
));
530 if (iclass
== asimdshf
)
532 Q
= extract_field (FLD_Q
, code
, 0);
534 0000 x SEE AdvSIMD modified immediate
544 get_vreg_qualifier_from_value ((pos
<< 1) | (int) Q
);
547 info
->qualifier
= get_sreg_qualifier_from_value (pos
);
549 if (info
->type
== AARCH64_OPND_IMM_VLSR
)
551 0000 SEE AdvSIMD modified immediate
552 0001 (16-UInt(immh:immb))
553 001x (32-UInt(immh:immb))
554 01xx (64-UInt(immh:immb))
555 1xxx (128-UInt(immh:immb)) */
556 info
->imm
.value
= (16 << pos
) - imm
;
560 0000 SEE AdvSIMD modified immediate
561 0001 (UInt(immh:immb)-8)
562 001x (UInt(immh:immb)-16)
563 01xx (UInt(immh:immb)-32)
564 1xxx (UInt(immh:immb)-64) */
565 info
->imm
.value
= imm
- (8 << pos
);
570 /* Decode shift immediate for e.g. sshr (imm). */
572 aarch64_ext_shll_imm (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
573 aarch64_opnd_info
*info
, const aarch64_insn code
,
574 const aarch64_inst
*inst ATTRIBUTE_UNUSED
)
578 val
= extract_field (FLD_size
, code
, 0);
581 case 0: imm
= 8; break;
582 case 1: imm
= 16; break;
583 case 2: imm
= 32; break;
586 info
->imm
.value
= imm
;
590 /* Decode imm for e.g. BFM <Wd>, <Wn>, #<immr>, #<imms>.
591 value in the field(s) will be extracted as unsigned immediate value. */
593 aarch64_ext_imm (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
594 const aarch64_insn code
,
595 const aarch64_inst
*inst ATTRIBUTE_UNUSED
)
599 imm
= extract_all_fields (self
, code
);
601 if (info
->type
== AARCH64_OPND_FPIMM
)
604 if (operand_need_sign_extension (self
))
605 imm
= sign_extend (imm
, get_operand_fields_width (self
) - 1);
607 if (operand_need_shift_by_two (self
))
610 if (info
->type
== AARCH64_OPND_ADDR_ADRP
)
613 info
->imm
.value
= imm
;
617 /* Decode imm and its shifter for e.g. MOVZ <Wd>, #<imm16>{, LSL #<shift>}. */
619 aarch64_ext_imm_half (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
620 const aarch64_insn code
,
621 const aarch64_inst
*inst ATTRIBUTE_UNUSED
)
623 aarch64_ext_imm (self
, info
, code
, inst
);
624 info
->shifter
.kind
= AARCH64_MOD_LSL
;
625 info
->shifter
.amount
= extract_field (FLD_hw
, code
, 0) << 4;
629 /* Decode cmode and "a:b:c:d:e:f:g:h" for e.g.
630 MOVI <Vd>.<T>, #<imm8> {, LSL #<amount>}. */
632 aarch64_ext_advsimd_imm_modified (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
633 aarch64_opnd_info
*info
,
634 const aarch64_insn code
,
635 const aarch64_inst
*inst ATTRIBUTE_UNUSED
)
638 enum aarch64_opnd_qualifier opnd0_qualifier
= inst
->operands
[0].qualifier
;
639 aarch64_field field
= {0, 0};
641 assert (info
->idx
== 1);
643 if (info
->type
== AARCH64_OPND_SIMD_FPIMM
)
646 /* a:b:c:d:e:f:g:h */
647 imm
= extract_fields (code
, 0, 2, FLD_abc
, FLD_defgh
);
648 if (!info
->imm
.is_fp
&& aarch64_get_qualifier_esize (opnd0_qualifier
) == 8)
650 /* Either MOVI <Dd>, #<imm>
651 or MOVI <Vd>.2D, #<imm>.
652 <imm> is a 64-bit immediate
653 'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh',
654 encoded in "a:b:c:d:e:f:g:h". */
656 unsigned abcdefgh
= imm
;
657 for (imm
= 0ull, i
= 0; i
< 8; i
++)
658 if (((abcdefgh
>> i
) & 0x1) != 0)
659 imm
|= 0xffull
<< (8 * i
);
661 info
->imm
.value
= imm
;
664 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
665 switch (info
->qualifier
)
667 case AARCH64_OPND_QLF_NIL
:
669 info
->shifter
.kind
= AARCH64_MOD_NONE
;
671 case AARCH64_OPND_QLF_LSL
:
673 info
->shifter
.kind
= AARCH64_MOD_LSL
;
674 switch (aarch64_get_qualifier_esize (opnd0_qualifier
))
676 case 4: gen_sub_field (FLD_cmode
, 1, 2, &field
); break; /* per word */
677 case 2: gen_sub_field (FLD_cmode
, 1, 1, &field
); break; /* per half */
678 case 1: gen_sub_field (FLD_cmode
, 1, 0, &field
); break; /* per byte */
679 default: assert (0); return 0;
681 /* 00: 0; 01: 8; 10:16; 11:24. */
682 info
->shifter
.amount
= extract_field_2 (&field
, code
, 0) << 3;
684 case AARCH64_OPND_QLF_MSL
:
686 info
->shifter
.kind
= AARCH64_MOD_MSL
;
687 gen_sub_field (FLD_cmode
, 0, 1, &field
); /* per word */
688 info
->shifter
.amount
= extract_field_2 (&field
, code
, 0) ? 16 : 8;
698 /* Decode scale for e.g. SCVTF <Dd>, <Wn>, #<fbits>. */
700 aarch64_ext_fbits (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
701 aarch64_opnd_info
*info
, const aarch64_insn code
,
702 const aarch64_inst
*inst ATTRIBUTE_UNUSED
)
704 info
->imm
.value
= 64- extract_field (FLD_scale
, code
, 0);
708 /* Decode arithmetic immediate for e.g.
709 SUBS <Wd>, <Wn|WSP>, #<imm> {, <shift>}. */
711 aarch64_ext_aimm (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
712 aarch64_opnd_info
*info
, const aarch64_insn code
,
713 const aarch64_inst
*inst ATTRIBUTE_UNUSED
)
717 info
->shifter
.kind
= AARCH64_MOD_LSL
;
719 value
= extract_field (FLD_shift
, code
, 0);
722 info
->shifter
.amount
= value
? 12 : 0;
723 /* imm12 (unsigned) */
724 info
->imm
.value
= extract_field (FLD_imm12
, code
, 0);
729 /* Decode logical immediate for e.g. ORR <Wd|WSP>, <Wn>, #<imm>. */
732 aarch64_ext_limm (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
733 aarch64_opnd_info
*info
, const aarch64_insn code
,
734 const aarch64_inst
*inst ATTRIBUTE_UNUSED
)
742 value
= extract_fields (code
, 0, 3, FLD_N
, FLD_immr
, FLD_imms
);
743 assert (inst
->operands
[0].qualifier
== AARCH64_OPND_QLF_W
744 || inst
->operands
[0].qualifier
== AARCH64_OPND_QLF_X
);
745 sf
= aarch64_get_qualifier_esize (inst
->operands
[0].qualifier
) != 4;
747 /* value is N:immr:imms. */
749 R
= (value
>> 6) & 0x3f;
750 N
= (value
>> 12) & 0x1;
752 if (sf
== 0 && N
== 1)
755 /* The immediate value is S+1 bits to 1, left rotated by SIMDsize - R
756 (in other words, right rotated by R), then replicated. */
760 mask
= 0xffffffffffffffffull
;
766 case 0x00 ... 0x1f: /* 0xxxxx */ simd_size
= 32; break;
767 case 0x20 ... 0x2f: /* 10xxxx */ simd_size
= 16; S
&= 0xf; break;
768 case 0x30 ... 0x37: /* 110xxx */ simd_size
= 8; S
&= 0x7; break;
769 case 0x38 ... 0x3b: /* 1110xx */ simd_size
= 4; S
&= 0x3; break;
770 case 0x3c ... 0x3d: /* 11110x */ simd_size
= 2; S
&= 0x1; break;
773 mask
= (1ull << simd_size
) - 1;
774 /* Top bits are IGNORED. */
777 /* NOTE: if S = simd_size - 1 we get 0xf..f which is rejected. */
778 if (S
== simd_size
- 1)
780 /* S+1 consecutive bits to 1. */
781 /* NOTE: S can't be 63 due to detection above. */
782 imm
= (1ull << (S
+ 1)) - 1;
783 /* Rotate to the left by simd_size - R. */
785 imm
= ((imm
<< (simd_size
- R
)) & mask
) | (imm
>> R
);
786 /* Replicate the value according to SIMD size. */
789 case 2: imm
= (imm
<< 2) | imm
;
790 case 4: imm
= (imm
<< 4) | imm
;
791 case 8: imm
= (imm
<< 8) | imm
;
792 case 16: imm
= (imm
<< 16) | imm
;
793 case 32: imm
= (imm
<< 32) | imm
;
795 default: assert (0); return 0;
798 info
->imm
.value
= sf
? imm
: imm
& 0xffffffff;
803 /* Decode Ft for e.g. STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]
804 or LDP <Qt1>, <Qt2>, [<Xn|SP>], #<imm>. */
806 aarch64_ext_ft (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
807 aarch64_opnd_info
*info
,
808 const aarch64_insn code
, const aarch64_inst
*inst
)
813 info
->reg
.regno
= extract_field (FLD_Rt
, code
, 0);
816 value
= extract_field (FLD_ldst_size
, code
, 0);
817 if (inst
->opcode
->iclass
== ldstpair_indexed
818 || inst
->opcode
->iclass
== ldstnapair_offs
819 || inst
->opcode
->iclass
== ldstpair_off
820 || inst
->opcode
->iclass
== loadlit
)
822 enum aarch64_opnd_qualifier qualifier
;
825 case 0: qualifier
= AARCH64_OPND_QLF_S_S
; break;
826 case 1: qualifier
= AARCH64_OPND_QLF_S_D
; break;
827 case 2: qualifier
= AARCH64_OPND_QLF_S_Q
; break;
830 info
->qualifier
= qualifier
;
835 value
= extract_fields (code
, 0, 2, FLD_opc1
, FLD_ldst_size
);
838 info
->qualifier
= get_sreg_qualifier_from_value (value
);
844 /* Decode the address operand for e.g. STXRB <Ws>, <Wt>, [<Xn|SP>{,#0}]. */
846 aarch64_ext_addr_simple (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
847 aarch64_opnd_info
*info
,
849 const aarch64_inst
*inst ATTRIBUTE_UNUSED
)
852 info
->addr
.base_regno
= extract_field (FLD_Rn
, code
, 0);
856 /* Decode the address operand for e.g.
857 STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]. */
859 aarch64_ext_addr_regoff (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
860 aarch64_opnd_info
*info
,
861 aarch64_insn code
, const aarch64_inst
*inst
)
863 aarch64_insn S
, value
;
866 info
->addr
.base_regno
= extract_field (FLD_Rn
, code
, 0);
868 info
->addr
.offset
.regno
= extract_field (FLD_Rm
, code
, 0);
870 value
= extract_field (FLD_option
, code
, 0);
872 aarch64_get_operand_modifier_from_value (value
, TRUE
/* extend_p */);
873 /* Fix-up the shifter kind; although the table-driven approach is
874 efficient, it is slightly inflexible, thus needing this fix-up. */
875 if (info
->shifter
.kind
== AARCH64_MOD_UXTX
)
876 info
->shifter
.kind
= AARCH64_MOD_LSL
;
878 S
= extract_field (FLD_S
, code
, 0);
881 info
->shifter
.amount
= 0;
882 info
->shifter
.amount_present
= 0;
887 /* Need information in other operand(s) to help achieve the decoding
889 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
890 /* Get the size of the data element that is accessed, which may be
891 different from that of the source register size, e.g. in strb/ldrb. */
892 size
= aarch64_get_qualifier_esize (info
->qualifier
);
893 info
->shifter
.amount
= get_logsz (size
);
894 info
->shifter
.amount_present
= 1;
900 /* Decode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>], #<simm>. */
902 aarch64_ext_addr_simm (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
903 aarch64_insn code
, const aarch64_inst
*inst
)
906 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
909 info
->addr
.base_regno
= extract_field (FLD_Rn
, code
, 0);
910 /* simm (imm9 or imm7) */
911 imm
= extract_field (self
->fields
[0], code
, 0);
912 info
->addr
.offset
.imm
= sign_extend (imm
, fields
[self
->fields
[0]].width
- 1);
913 if (self
->fields
[0] == FLD_imm7
)
914 /* scaled immediate in ld/st pair instructions. */
915 info
->addr
.offset
.imm
*= aarch64_get_qualifier_esize (info
->qualifier
);
917 if (inst
->opcode
->iclass
== ldst_unscaled
918 || inst
->opcode
->iclass
== ldstnapair_offs
919 || inst
->opcode
->iclass
== ldstpair_off
920 || inst
->opcode
->iclass
== ldst_unpriv
)
921 info
->addr
.writeback
= 0;
924 /* pre/post- index */
925 info
->addr
.writeback
= 1;
926 if (extract_field (self
->fields
[1], code
, 0) == 1)
927 info
->addr
.preind
= 1;
929 info
->addr
.postind
= 1;
935 /* Decode the address operand for e.g. LDRSW <Xt>, [<Xn|SP>{, #<simm>}]. */
937 aarch64_ext_addr_uimm12 (const aarch64_operand
*self
, aarch64_opnd_info
*info
,
939 const aarch64_inst
*inst ATTRIBUTE_UNUSED
)
942 info
->qualifier
= get_expected_qualifier (inst
, info
->idx
);
943 shift
= get_logsz (aarch64_get_qualifier_esize (info
->qualifier
));
945 info
->addr
.base_regno
= extract_field (self
->fields
[0], code
, 0);
947 info
->addr
.offset
.imm
= extract_field (self
->fields
[1], code
, 0) << shift
;
951 /* Decode the address operand for e.g.
952 LD1 {<Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>}, [<Xn|SP>], <Xm|#<amount>>. */
954 aarch64_ext_simd_addr_post (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
955 aarch64_opnd_info
*info
,
956 aarch64_insn code
, const aarch64_inst
*inst
)
958 /* The opcode dependent area stores the number of elements in
959 each structure to be loaded/stored. */
960 int is_ld1r
= get_opcode_dependent_value (inst
->opcode
) == 1;
963 info
->addr
.base_regno
= extract_field (FLD_Rn
, code
, 0);
965 info
->addr
.offset
.regno
= extract_field (FLD_Rm
, code
, 0);
966 if (info
->addr
.offset
.regno
== 31)
968 if (inst
->opcode
->operands
[0] == AARCH64_OPND_LVt_AL
)
969 /* Special handling of loading single structure to all lane. */
970 info
->addr
.offset
.imm
= (is_ld1r
? 1
971 : inst
->operands
[0].reglist
.num_regs
)
972 * aarch64_get_qualifier_esize (inst
->operands
[0].qualifier
);
974 info
->addr
.offset
.imm
= inst
->operands
[0].reglist
.num_regs
975 * aarch64_get_qualifier_esize (inst
->operands
[0].qualifier
)
976 * aarch64_get_qualifier_nelem (inst
->operands
[0].qualifier
);
979 info
->addr
.offset
.is_reg
= 1;
980 info
->addr
.writeback
= 1;
985 /* Decode the condition operand for e.g. CSEL <Xd>, <Xn>, <Xm>, <cond>. */
987 aarch64_ext_cond (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
988 aarch64_opnd_info
*info
,
989 aarch64_insn code
, const aarch64_inst
*inst ATTRIBUTE_UNUSED
)
993 value
= extract_field (FLD_cond
, code
, 0);
994 info
->cond
= get_cond_from_value (value
);
998 /* Decode the system register operand for e.g. MRS <Xt>, <systemreg>. */
1000 aarch64_ext_sysreg (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1001 aarch64_opnd_info
*info
,
1003 const aarch64_inst
*inst ATTRIBUTE_UNUSED
)
1005 /* op0:op1:CRn:CRm:op2 */
1006 info
->sysreg
= extract_fields (code
, 0, 5, FLD_op0
, FLD_op1
, FLD_CRn
,
1011 /* Decode the PSTATE field operand for e.g. MSR <pstatefield>, #<imm>. */
1013 aarch64_ext_pstatefield (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1014 aarch64_opnd_info
*info
, aarch64_insn code
,
1015 const aarch64_inst
*inst ATTRIBUTE_UNUSED
)
1019 info
->pstatefield
= extract_fields (code
, 0, 2, FLD_op1
, FLD_op2
);
1020 for (i
= 0; aarch64_pstatefields
[i
].name
!= NULL
; ++i
)
1021 if (aarch64_pstatefields
[i
].value
== (aarch64_insn
)info
->pstatefield
)
1023 /* Reserved value in <pstatefield>. */
1027 /* Decode the system instruction op operand for e.g. AT <at_op>, <Xt>. */
1029 aarch64_ext_sysins_op (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1030 aarch64_opnd_info
*info
,
1032 const aarch64_inst
*inst ATTRIBUTE_UNUSED
)
1036 const aarch64_sys_ins_reg
*sysins_ops
;
1037 /* op0:op1:CRn:CRm:op2 */
1038 value
= extract_fields (code
, 0, 5,
1039 FLD_op0
, FLD_op1
, FLD_CRn
,
1044 case AARCH64_OPND_SYSREG_AT
: sysins_ops
= aarch64_sys_regs_at
; break;
1045 case AARCH64_OPND_SYSREG_DC
: sysins_ops
= aarch64_sys_regs_dc
; break;
1046 case AARCH64_OPND_SYSREG_IC
: sysins_ops
= aarch64_sys_regs_ic
; break;
1047 case AARCH64_OPND_SYSREG_TLBI
: sysins_ops
= aarch64_sys_regs_tlbi
; break;
1048 default: assert (0); return 0;
1051 for (i
= 0; sysins_ops
[i
].name
!= NULL
; ++i
)
1052 if (sysins_ops
[i
].value
== value
)
1054 info
->sysins_op
= sysins_ops
+ i
;
1055 DEBUG_TRACE ("%s found value: %x, has_xt: %d, i: %d.",
1056 info
->sysins_op
->name
,
1057 (unsigned)info
->sysins_op
->value
,
1058 aarch64_sys_ins_reg_has_xt (info
->sysins_op
), i
);
1065 /* Decode the memory barrier option operand for e.g. DMB <option>|#<imm>. */
1068 aarch64_ext_barrier (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1069 aarch64_opnd_info
*info
,
1071 const aarch64_inst
*inst ATTRIBUTE_UNUSED
)
1074 info
->barrier
= aarch64_barrier_options
+ extract_field (FLD_CRm
, code
, 0);
1078 /* Decode the prefetch operation option operand for e.g.
1079 PRFM <prfop>, [<Xn|SP>{, #<pimm>}]. */
1082 aarch64_ext_prfop (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1083 aarch64_opnd_info
*info
,
1084 aarch64_insn code
, const aarch64_inst
*inst ATTRIBUTE_UNUSED
)
1087 info
->prfop
= aarch64_prfops
+ extract_field (FLD_Rt
, code
, 0);
1091 /* Decode the hint number for an alias taking an operand. Set info->hint_option
1092 to the matching name/value pair in aarch64_hint_options. */
1095 aarch64_ext_hint (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1096 aarch64_opnd_info
*info
,
1098 const aarch64_inst
*inst ATTRIBUTE_UNUSED
)
1101 unsigned hint_number
;
1104 hint_number
= extract_fields (code
, 0, 2, FLD_CRm
, FLD_op2
);
1106 for (i
= 0; aarch64_hint_options
[i
].name
!= NULL
; i
++)
1108 if (hint_number
== aarch64_hint_options
[i
].value
)
1110 info
->hint_option
= &(aarch64_hint_options
[i
]);
1118 /* Decode the extended register operand for e.g.
1119 STR <Qt>, [<Xn|SP>, <R><m>{, <extend> {<amount>}}]. */
1121 aarch64_ext_reg_extended (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1122 aarch64_opnd_info
*info
,
1124 const aarch64_inst
*inst ATTRIBUTE_UNUSED
)
1129 info
->reg
.regno
= extract_field (FLD_Rm
, code
, 0);
1131 value
= extract_field (FLD_option
, code
, 0);
1132 info
->shifter
.kind
=
1133 aarch64_get_operand_modifier_from_value (value
, TRUE
/* extend_p */);
1135 info
->shifter
.amount
= extract_field (FLD_imm3
, code
, 0);
1137 /* This makes the constraint checking happy. */
1138 info
->shifter
.operator_present
= 1;
1140 /* Assume inst->operands[0].qualifier has been resolved. */
1141 assert (inst
->operands
[0].qualifier
!= AARCH64_OPND_QLF_NIL
);
1142 info
->qualifier
= AARCH64_OPND_QLF_W
;
1143 if (inst
->operands
[0].qualifier
== AARCH64_OPND_QLF_X
1144 && (info
->shifter
.kind
== AARCH64_MOD_UXTX
1145 || info
->shifter
.kind
== AARCH64_MOD_SXTX
))
1146 info
->qualifier
= AARCH64_OPND_QLF_X
;
1151 /* Decode the shifted register operand for e.g.
1152 SUBS <Xd>, <Xn>, <Xm> {, <shift> #<amount>}. */
1154 aarch64_ext_reg_shifted (const aarch64_operand
*self ATTRIBUTE_UNUSED
,
1155 aarch64_opnd_info
*info
,
1157 const aarch64_inst
*inst ATTRIBUTE_UNUSED
)
1162 info
->reg
.regno
= extract_field (FLD_Rm
, code
, 0);
1164 value
= extract_field (FLD_shift
, code
, 0);
1165 info
->shifter
.kind
=
1166 aarch64_get_operand_modifier_from_value (value
, FALSE
/* extend_p */);
1167 if (info
->shifter
.kind
== AARCH64_MOD_ROR
1168 && inst
->opcode
->iclass
!= log_shift
)
1169 /* ROR is not available for the shifted register operand in arithmetic
1173 info
->shifter
.amount
= extract_field (FLD_imm6
, code
, 0);
1175 /* This makes the constraint checking happy. */
1176 info
->shifter
.operator_present
= 1;
1181 /* Bitfields that are commonly used to encode certain operands' information
1182 may be partially used as part of the base opcode in some instructions.
1183 For example, the bit 1 of the field 'size' in
1184 FCVTXN <Vb><d>, <Va><n>
1185 is actually part of the base opcode, while only size<0> is available
1186 for encoding the register type. Another example is the AdvSIMD
1187 instruction ORR (register), in which the field 'size' is also used for
1188 the base opcode, leaving only the field 'Q' available to encode the
1189 vector register arrangement specifier '8B' or '16B'.
1191 This function tries to deduce the qualifier from the value of partially
1192 constrained field(s). Given the VALUE of such a field or fields, the
1193 qualifiers CANDIDATES and the MASK (indicating which bits are valid for
1194 operand encoding), the function returns the matching qualifier or
1195 AARCH64_OPND_QLF_NIL if nothing matches.
1197 N.B. CANDIDATES is a group of possible qualifiers that are valid for
1198 one operand; it has a maximum of AARCH64_MAX_QLF_SEQ_NUM qualifiers and
1199 may end with AARCH64_OPND_QLF_NIL. */
1201 static enum aarch64_opnd_qualifier
1202 get_qualifier_from_partial_encoding (aarch64_insn value
,
1203 const enum aarch64_opnd_qualifier
* \
1208 DEBUG_TRACE ("enter with value: %d, mask: %d", (int)value
, (int)mask
);
1209 for (i
= 0; i
< AARCH64_MAX_QLF_SEQ_NUM
; ++i
)
1211 aarch64_insn standard_value
;
1212 if (candidates
[i
] == AARCH64_OPND_QLF_NIL
)
1214 standard_value
= aarch64_get_qualifier_standard_value (candidates
[i
]);
1215 if ((standard_value
& mask
) == (value
& mask
))
1216 return candidates
[i
];
1218 return AARCH64_OPND_QLF_NIL
;
1221 /* Given a list of qualifier sequences, return all possible valid qualifiers
1222 for operand IDX in QUALIFIERS.
1223 Assume QUALIFIERS is an array whose length is large enough. */
1226 get_operand_possible_qualifiers (int idx
,
1227 const aarch64_opnd_qualifier_seq_t
*list
,
1228 enum aarch64_opnd_qualifier
*qualifiers
)
1231 for (i
= 0; i
< AARCH64_MAX_QLF_SEQ_NUM
; ++i
)
1232 if ((qualifiers
[i
] = list
[i
][idx
]) == AARCH64_OPND_QLF_NIL
)
1236 /* Decode the size Q field for e.g. SHADD.
1237 We tag one operand with the qualifer according to the code;
1238 whether the qualifier is valid for this opcode or not, it is the
1239 duty of the semantic checking. */
1242 decode_sizeq (aarch64_inst
*inst
)
1245 enum aarch64_opnd_qualifier qualifier
;
1247 aarch64_insn value
, mask
;
1248 enum aarch64_field_kind fld_sz
;
1249 enum aarch64_opnd_qualifier candidates
[AARCH64_MAX_QLF_SEQ_NUM
];
1251 if (inst
->opcode
->iclass
== asisdlse
1252 || inst
->opcode
->iclass
== asisdlsep
1253 || inst
->opcode
->iclass
== asisdlso
1254 || inst
->opcode
->iclass
== asisdlsop
)
1255 fld_sz
= FLD_vldst_size
;
1260 value
= extract_fields (code
, inst
->opcode
->mask
, 2, fld_sz
, FLD_Q
);
1261 /* Obtain the info that which bits of fields Q and size are actually
1262 available for operand encoding. Opcodes like FMAXNM and FMLA have
1263 size[1] unavailable. */
1264 mask
= extract_fields (~inst
->opcode
->mask
, 0, 2, fld_sz
, FLD_Q
);
1266 /* The index of the operand we are going to tag a qualifier and the qualifer
1267 itself are reasoned from the value of the size and Q fields and the
1268 possible valid qualifier lists. */
1269 idx
= aarch64_select_operand_for_sizeq_field_coding (inst
->opcode
);
1270 DEBUG_TRACE ("key idx: %d", idx
);
1272 /* For most related instruciton, size:Q are fully available for operand
1276 inst
->operands
[idx
].qualifier
= get_vreg_qualifier_from_value (value
);
1280 get_operand_possible_qualifiers (idx
, inst
->opcode
->qualifiers_list
,
1282 #ifdef DEBUG_AARCH64
1286 for (i
= 0; candidates
[i
] != AARCH64_OPND_QLF_NIL
1287 && i
< AARCH64_MAX_QLF_SEQ_NUM
; ++i
)
1288 DEBUG_TRACE ("qualifier %d: %s", i
,
1289 aarch64_get_qualifier_name(candidates
[i
]));
1290 DEBUG_TRACE ("%d, %d", (int)value
, (int)mask
);
1292 #endif /* DEBUG_AARCH64 */
1294 qualifier
= get_qualifier_from_partial_encoding (value
, candidates
, mask
);
1296 if (qualifier
== AARCH64_OPND_QLF_NIL
)
1299 inst
->operands
[idx
].qualifier
= qualifier
;
1303 /* Decode size[0]:Q, i.e. bit 22 and bit 30, for
1304 e.g. FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>. */
1307 decode_asimd_fcvt (aarch64_inst
*inst
)
1309 aarch64_field field
= {0, 0};
1311 enum aarch64_opnd_qualifier qualifier
;
1313 gen_sub_field (FLD_size
, 0, 1, &field
);
1314 value
= extract_field_2 (&field
, inst
->value
, 0);
1315 qualifier
= value
== 0 ? AARCH64_OPND_QLF_V_4S
1316 : AARCH64_OPND_QLF_V_2D
;
1317 switch (inst
->opcode
->op
)
1321 /* FCVTN<Q> <Vd>.<Tb>, <Vn>.<Ta>. */
1322 inst
->operands
[1].qualifier
= qualifier
;
1326 /* FCVTL<Q> <Vd>.<Ta>, <Vn>.<Tb>. */
1327 inst
->operands
[0].qualifier
= qualifier
;
1337 /* Decode size[0], i.e. bit 22, for
1338 e.g. FCVTXN <Vb><d>, <Va><n>. */
1341 decode_asisd_fcvtxn (aarch64_inst
*inst
)
1343 aarch64_field field
= {0, 0};
1344 gen_sub_field (FLD_size
, 0, 1, &field
);
1345 if (!extract_field_2 (&field
, inst
->value
, 0))
1347 inst
->operands
[0].qualifier
= AARCH64_OPND_QLF_S_S
;
1351 /* Decode the 'opc' field for e.g. FCVT <Dd>, <Sn>. */
1353 decode_fcvt (aarch64_inst
*inst
)
1355 enum aarch64_opnd_qualifier qualifier
;
1357 const aarch64_field field
= {15, 2};
1360 value
= extract_field_2 (&field
, inst
->value
, 0);
1363 case 0: qualifier
= AARCH64_OPND_QLF_S_S
; break;
1364 case 1: qualifier
= AARCH64_OPND_QLF_S_D
; break;
1365 case 3: qualifier
= AARCH64_OPND_QLF_S_H
; break;
1368 inst
->operands
[0].qualifier
= qualifier
;
1373 /* Do miscellaneous decodings that are not common enough to be driven by
1377 do_misc_decoding (aarch64_inst
*inst
)
1379 switch (inst
->opcode
->op
)
1382 return decode_fcvt (inst
);
1387 return decode_asimd_fcvt (inst
);
1389 return decode_asisd_fcvtxn (inst
);
1395 /* Opcodes that have fields shared by multiple operands are usually flagged
1396 with flags. In this function, we detect such flags, decode the related
1397 field(s) and store the information in one of the related operands. The
1398 'one' operand is not any operand but one of the operands that can
1399 accommadate all the information that has been decoded. */
1402 do_special_decoding (aarch64_inst
*inst
)
1406 /* Condition for truly conditional executed instructions, e.g. b.cond. */
1407 if (inst
->opcode
->flags
& F_COND
)
1409 value
= extract_field (FLD_cond2
, inst
->value
, 0);
1410 inst
->cond
= get_cond_from_value (value
);
1413 if (inst
->opcode
->flags
& F_SF
)
1415 idx
= select_operand_for_sf_field_coding (inst
->opcode
);
1416 value
= extract_field (FLD_sf
, inst
->value
, 0);
1417 inst
->operands
[idx
].qualifier
= get_greg_qualifier_from_value (value
);
1418 if ((inst
->opcode
->flags
& F_N
)
1419 && extract_field (FLD_N
, inst
->value
, 0) != value
)
1423 if (inst
->opcode
->flags
& F_LSE_SZ
)
1425 idx
= select_operand_for_sf_field_coding (inst
->opcode
);
1426 value
= extract_field (FLD_lse_sz
, inst
->value
, 0);
1427 inst
->operands
[idx
].qualifier
= get_greg_qualifier_from_value (value
);
1429 /* size:Q fields. */
1430 if (inst
->opcode
->flags
& F_SIZEQ
)
1431 return decode_sizeq (inst
);
1433 if (inst
->opcode
->flags
& F_FPTYPE
)
1435 idx
= select_operand_for_fptype_field_coding (inst
->opcode
);
1436 value
= extract_field (FLD_type
, inst
->value
, 0);
1439 case 0: inst
->operands
[idx
].qualifier
= AARCH64_OPND_QLF_S_S
; break;
1440 case 1: inst
->operands
[idx
].qualifier
= AARCH64_OPND_QLF_S_D
; break;
1441 case 3: inst
->operands
[idx
].qualifier
= AARCH64_OPND_QLF_S_H
; break;
1446 if (inst
->opcode
->flags
& F_SSIZE
)
1448 /* N.B. some opcodes like FCMGT <V><d>, <V><n>, #0 have the size[1] as part
1449 of the base opcode. */
1451 enum aarch64_opnd_qualifier candidates
[AARCH64_MAX_QLF_SEQ_NUM
];
1452 idx
= select_operand_for_scalar_size_field_coding (inst
->opcode
);
1453 value
= extract_field (FLD_size
, inst
->value
, inst
->opcode
->mask
);
1454 mask
= extract_field (FLD_size
, ~inst
->opcode
->mask
, 0);
1455 /* For most related instruciton, the 'size' field is fully available for
1456 operand encoding. */
1458 inst
->operands
[idx
].qualifier
= get_sreg_qualifier_from_value (value
);
1461 get_operand_possible_qualifiers (idx
, inst
->opcode
->qualifiers_list
,
1463 inst
->operands
[idx
].qualifier
1464 = get_qualifier_from_partial_encoding (value
, candidates
, mask
);
1468 if (inst
->opcode
->flags
& F_T
)
1470 /* Num of consecutive '0's on the right side of imm5<3:0>. */
1473 assert (aarch64_get_operand_class (inst
->opcode
->operands
[0])
1474 == AARCH64_OPND_CLASS_SIMD_REG
);
1485 val
= extract_field (FLD_imm5
, inst
->value
, 0);
1486 while ((val
& 0x1) == 0 && ++num
<= 3)
1490 Q
= (unsigned) extract_field (FLD_Q
, inst
->value
, inst
->opcode
->mask
);
1491 inst
->operands
[0].qualifier
=
1492 get_vreg_qualifier_from_value ((num
<< 1) | Q
);
1495 if (inst
->opcode
->flags
& F_GPRSIZE_IN_Q
)
1497 /* Use Rt to encode in the case of e.g.
1498 STXP <Ws>, <Xt1>, <Xt2>, [<Xn|SP>{,#0}]. */
1499 idx
= aarch64_operand_index (inst
->opcode
->operands
, AARCH64_OPND_Rt
);
1502 /* Otherwise use the result operand, which has to be a integer
1504 assert (aarch64_get_operand_class (inst
->opcode
->operands
[0])
1505 == AARCH64_OPND_CLASS_INT_REG
);
1508 assert (idx
== 0 || idx
== 1);
1509 value
= extract_field (FLD_Q
, inst
->value
, 0);
1510 inst
->operands
[idx
].qualifier
= get_greg_qualifier_from_value (value
);
1513 if (inst
->opcode
->flags
& F_LDS_SIZE
)
1515 aarch64_field field
= {0, 0};
1516 assert (aarch64_get_operand_class (inst
->opcode
->operands
[0])
1517 == AARCH64_OPND_CLASS_INT_REG
);
1518 gen_sub_field (FLD_opc
, 0, 1, &field
);
1519 value
= extract_field_2 (&field
, inst
->value
, 0);
1520 inst
->operands
[0].qualifier
1521 = value
? AARCH64_OPND_QLF_W
: AARCH64_OPND_QLF_X
;
1524 /* Miscellaneous decoding; done as the last step. */
1525 if (inst
->opcode
->flags
& F_MISC
)
1526 return do_misc_decoding (inst
);
1531 /* Converters converting a real opcode instruction to its alias form. */
1533 /* ROR <Wd>, <Ws>, #<shift>
1535 EXTR <Wd>, <Ws>, <Ws>, #<shift>. */
1537 convert_extr_to_ror (aarch64_inst
*inst
)
1539 if (inst
->operands
[1].reg
.regno
== inst
->operands
[2].reg
.regno
)
1541 copy_operand_info (inst
, 2, 3);
1542 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
1548 /* UXTL<Q> <Vd>.<Ta>, <Vn>.<Tb>
1550 USHLL<Q> <Vd>.<Ta>, <Vn>.<Tb>, #0. */
1552 convert_shll_to_xtl (aarch64_inst
*inst
)
1554 if (inst
->operands
[2].imm
.value
== 0)
1556 inst
->operands
[2].type
= AARCH64_OPND_NIL
;
1563 UBFM <Xd>, <Xn>, #<shift>, #63.
1565 LSR <Xd>, <Xn>, #<shift>. */
1567 convert_bfm_to_sr (aarch64_inst
*inst
)
1571 imms
= inst
->operands
[3].imm
.value
;
1572 val
= inst
->operands
[2].qualifier
== AARCH64_OPND_QLF_imm_0_31
? 31 : 63;
1575 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
1582 /* Convert MOV to ORR. */
1584 convert_orr_to_mov (aarch64_inst
*inst
)
1586 /* MOV <Vd>.<T>, <Vn>.<T>
1588 ORR <Vd>.<T>, <Vn>.<T>, <Vn>.<T>. */
1589 if (inst
->operands
[1].reg
.regno
== inst
->operands
[2].reg
.regno
)
1591 inst
->operands
[2].type
= AARCH64_OPND_NIL
;
1597 /* When <imms> >= <immr>, the instruction written:
1598 SBFX <Xd>, <Xn>, #<lsb>, #<width>
1600 SBFM <Xd>, <Xn>, #<lsb>, #(<lsb>+<width>-1). */
1603 convert_bfm_to_bfx (aarch64_inst
*inst
)
1607 immr
= inst
->operands
[2].imm
.value
;
1608 imms
= inst
->operands
[3].imm
.value
;
1612 inst
->operands
[2].imm
.value
= lsb
;
1613 inst
->operands
[3].imm
.value
= imms
+ 1 - lsb
;
1614 /* The two opcodes have different qualifiers for
1615 the immediate operands; reset to help the checking. */
1616 reset_operand_qualifier (inst
, 2);
1617 reset_operand_qualifier (inst
, 3);
1624 /* When <imms> < <immr>, the instruction written:
1625 SBFIZ <Xd>, <Xn>, #<lsb>, #<width>
1627 SBFM <Xd>, <Xn>, #((64-<lsb>)&0x3f), #(<width>-1). */
1630 convert_bfm_to_bfi (aarch64_inst
*inst
)
1632 int64_t immr
, imms
, val
;
1634 immr
= inst
->operands
[2].imm
.value
;
1635 imms
= inst
->operands
[3].imm
.value
;
1636 val
= inst
->operands
[2].qualifier
== AARCH64_OPND_QLF_imm_0_31
? 32 : 64;
1639 inst
->operands
[2].imm
.value
= (val
- immr
) & (val
- 1);
1640 inst
->operands
[3].imm
.value
= imms
+ 1;
1641 /* The two opcodes have different qualifiers for
1642 the immediate operands; reset to help the checking. */
1643 reset_operand_qualifier (inst
, 2);
1644 reset_operand_qualifier (inst
, 3);
1651 /* The instruction written:
1652 BFC <Xd>, #<lsb>, #<width>
1654 BFM <Xd>, XZR, #((64-<lsb>)&0x3f), #(<width>-1). */
1657 convert_bfm_to_bfc (aarch64_inst
*inst
)
1659 int64_t immr
, imms
, val
;
1661 /* Should have been assured by the base opcode value. */
1662 assert (inst
->operands
[1].reg
.regno
== 0x1f);
1664 immr
= inst
->operands
[2].imm
.value
;
1665 imms
= inst
->operands
[3].imm
.value
;
1666 val
= inst
->operands
[2].qualifier
== AARCH64_OPND_QLF_imm_0_31
? 32 : 64;
1669 /* Drop XZR from the second operand. */
1670 copy_operand_info (inst
, 1, 2);
1671 copy_operand_info (inst
, 2, 3);
1672 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
1674 /* Recalculate the immediates. */
1675 inst
->operands
[1].imm
.value
= (val
- immr
) & (val
- 1);
1676 inst
->operands
[2].imm
.value
= imms
+ 1;
1678 /* The two opcodes have different qualifiers for the operands; reset to
1679 help the checking. */
1680 reset_operand_qualifier (inst
, 1);
1681 reset_operand_qualifier (inst
, 2);
1682 reset_operand_qualifier (inst
, 3);
1690 /* The instruction written:
1691 LSL <Xd>, <Xn>, #<shift>
1693 UBFM <Xd>, <Xn>, #((64-<shift>)&0x3f), #(63-<shift>). */
1696 convert_ubfm_to_lsl (aarch64_inst
*inst
)
1698 int64_t immr
= inst
->operands
[2].imm
.value
;
1699 int64_t imms
= inst
->operands
[3].imm
.value
;
1701 = inst
->operands
[2].qualifier
== AARCH64_OPND_QLF_imm_0_31
? 31 : 63;
1703 if ((immr
== 0 && imms
== val
) || immr
== imms
+ 1)
1705 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
1706 inst
->operands
[2].imm
.value
= val
- imms
;
1713 /* CINC <Wd>, <Wn>, <cond>
1715 CSINC <Wd>, <Wn>, <Wn>, invert(<cond>)
1716 where <cond> is not AL or NV. */
1719 convert_from_csel (aarch64_inst
*inst
)
1721 if (inst
->operands
[1].reg
.regno
== inst
->operands
[2].reg
.regno
1722 && (inst
->operands
[3].cond
->value
& 0xe) != 0xe)
1724 copy_operand_info (inst
, 2, 3);
1725 inst
->operands
[2].cond
= get_inverted_cond (inst
->operands
[3].cond
);
1726 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
1732 /* CSET <Wd>, <cond>
1734 CSINC <Wd>, WZR, WZR, invert(<cond>)
1735 where <cond> is not AL or NV. */
1738 convert_csinc_to_cset (aarch64_inst
*inst
)
1740 if (inst
->operands
[1].reg
.regno
== 0x1f
1741 && inst
->operands
[2].reg
.regno
== 0x1f
1742 && (inst
->operands
[3].cond
->value
& 0xe) != 0xe)
1744 copy_operand_info (inst
, 1, 3);
1745 inst
->operands
[1].cond
= get_inverted_cond (inst
->operands
[3].cond
);
1746 inst
->operands
[3].type
= AARCH64_OPND_NIL
;
1747 inst
->operands
[2].type
= AARCH64_OPND_NIL
;
1755 MOVZ <Wd>, #<imm16>, LSL #<shift>.
1757 A disassembler may output ORR, MOVZ and MOVN as a MOV mnemonic, except when
1758 ORR has an immediate that could be generated by a MOVZ or MOVN instruction,
1759 or where a MOVN has an immediate that could be encoded by MOVZ, or where
1760 MOVZ/MOVN #0 have a shift amount other than LSL #0, in which case the
1761 machine-instruction mnemonic must be used. */
1764 convert_movewide_to_mov (aarch64_inst
*inst
)
1766 uint64_t value
= inst
->operands
[1].imm
.value
;
1767 /* MOVZ/MOVN #0 have a shift amount other than LSL #0. */
1768 if (value
== 0 && inst
->operands
[1].shifter
.amount
!= 0)
1770 inst
->operands
[1].type
= AARCH64_OPND_IMM_MOV
;
1771 inst
->operands
[1].shifter
.kind
= AARCH64_MOD_NONE
;
1772 value
<<= inst
->operands
[1].shifter
.amount
;
1773 /* As an alias convertor, it has to be clear that the INST->OPCODE
1774 is the opcode of the real instruction. */
1775 if (inst
->opcode
->op
== OP_MOVN
)
1777 int is32
= inst
->operands
[0].qualifier
== AARCH64_OPND_QLF_W
;
1779 /* A MOVN has an immediate that could be encoded by MOVZ. */
1780 if (aarch64_wide_constant_p (value
, is32
, NULL
) == TRUE
)
1783 inst
->operands
[1].imm
.value
= value
;
1784 inst
->operands
[1].shifter
.amount
= 0;
1790 ORR <Wd>, WZR, #<imm>.
1792 A disassembler may output ORR, MOVZ and MOVN as a MOV mnemonic, except when
1793 ORR has an immediate that could be generated by a MOVZ or MOVN instruction,
1794 or where a MOVN has an immediate that could be encoded by MOVZ, or where
1795 MOVZ/MOVN #0 have a shift amount other than LSL #0, in which case the
1796 machine-instruction mnemonic must be used. */
1799 convert_movebitmask_to_mov (aarch64_inst
*inst
)
1804 /* Should have been assured by the base opcode value. */
1805 assert (inst
->operands
[1].reg
.regno
== 0x1f);
1806 copy_operand_info (inst
, 1, 2);
1807 is32
= inst
->operands
[0].qualifier
== AARCH64_OPND_QLF_W
;
1808 inst
->operands
[1].type
= AARCH64_OPND_IMM_MOV
;
1809 value
= inst
->operands
[1].imm
.value
;
1810 /* ORR has an immediate that could be generated by a MOVZ or MOVN
1812 if (inst
->operands
[0].reg
.regno
!= 0x1f
1813 && (aarch64_wide_constant_p (value
, is32
, NULL
) == TRUE
1814 || aarch64_wide_constant_p (~value
, is32
, NULL
) == TRUE
))
1817 inst
->operands
[2].type
= AARCH64_OPND_NIL
;
1821 /* Some alias opcodes are disassembled by being converted from their real-form.
1822 N.B. INST->OPCODE is the real opcode rather than the alias. */
1825 convert_to_alias (aarch64_inst
*inst
, const aarch64_opcode
*alias
)
1831 return convert_bfm_to_sr (inst
);
1833 return convert_ubfm_to_lsl (inst
);
1837 return convert_from_csel (inst
);
1840 return convert_csinc_to_cset (inst
);
1844 return convert_bfm_to_bfx (inst
);
1848 return convert_bfm_to_bfi (inst
);
1850 return convert_bfm_to_bfc (inst
);
1852 return convert_orr_to_mov (inst
);
1853 case OP_MOV_IMM_WIDE
:
1854 case OP_MOV_IMM_WIDEN
:
1855 return convert_movewide_to_mov (inst
);
1856 case OP_MOV_IMM_LOG
:
1857 return convert_movebitmask_to_mov (inst
);
1859 return convert_extr_to_ror (inst
);
1864 return convert_shll_to_xtl (inst
);
1870 static int aarch64_opcode_decode (const aarch64_opcode
*, const aarch64_insn
,
1871 aarch64_inst
*, int);
1873 /* Given the instruction information in *INST, check if the instruction has
1874 any alias form that can be used to represent *INST. If the answer is yes,
1875 update *INST to be in the form of the determined alias. */
1877 /* In the opcode description table, the following flags are used in opcode
1878 entries to help establish the relations between the real and alias opcodes:
1880 F_ALIAS: opcode is an alias
1881 F_HAS_ALIAS: opcode has alias(es)
1884 F_P3: Disassembly preference priority 1-3 (the larger the
1885 higher). If nothing is specified, it is the priority
1886 0 by default, i.e. the lowest priority.
1888 Although the relation between the machine and the alias instructions are not
1889 explicitly described, it can be easily determined from the base opcode
1890 values, masks and the flags F_ALIAS and F_HAS_ALIAS in their opcode
1891 description entries:
1893 The mask of an alias opcode must be equal to or a super-set (i.e. more
1894 constrained) of that of the aliased opcode; so is the base opcode value.
1896 if (opcode_has_alias (real) && alias_opcode_p (opcode)
1897 && (opcode->mask & real->mask) == real->mask
1898 && (real->mask & opcode->opcode) == (real->mask & real->opcode))
1899 then OPCODE is an alias of, and only of, the REAL instruction
1901 The alias relationship is forced flat-structured to keep related algorithm
1902 simple; an opcode entry cannot be flagged with both F_ALIAS and F_HAS_ALIAS.
1904 During the disassembling, the decoding decision tree (in
1905 opcodes/aarch64-dis-2.c) always returns an machine instruction opcode entry;
1906 if the decoding of such a machine instruction succeeds (and -Mno-aliases is
1907 not specified), the disassembler will check whether there is any alias
1908 instruction exists for this real instruction. If there is, the disassembler
1909 will try to disassemble the 32-bit binary again using the alias's rule, or
1910 try to convert the IR to the form of the alias. In the case of the multiple
1911 aliases, the aliases are tried one by one from the highest priority
1912 (currently the flag F_P3) to the lowest priority (no priority flag), and the
1913 first succeeds first adopted.
1915 You may ask why there is a need for the conversion of IR from one form to
1916 another in handling certain aliases. This is because on one hand it avoids
1917 adding more operand code to handle unusual encoding/decoding; on other
1918 hand, during the disassembling, the conversion is an effective approach to
1919 check the condition of an alias (as an alias may be adopted only if certain
1920 conditions are met).
1922 In order to speed up the alias opcode lookup, aarch64-gen has preprocessed
1923 aarch64_opcode_table and generated aarch64_find_alias_opcode and
1924 aarch64_find_next_alias_opcode (in opcodes/aarch64-dis-2.c) to help. */
1927 determine_disassembling_preference (struct aarch64_inst
*inst
)
1929 const aarch64_opcode
*opcode
;
1930 const aarch64_opcode
*alias
;
1932 opcode
= inst
->opcode
;
1934 /* This opcode does not have an alias, so use itself. */
1935 if (opcode_has_alias (opcode
) == FALSE
)
1938 alias
= aarch64_find_alias_opcode (opcode
);
1941 #ifdef DEBUG_AARCH64
1944 const aarch64_opcode
*tmp
= alias
;
1945 printf ("#### LIST orderd: ");
1948 printf ("%s, ", tmp
->name
);
1949 tmp
= aarch64_find_next_alias_opcode (tmp
);
1953 #endif /* DEBUG_AARCH64 */
1955 for (; alias
; alias
= aarch64_find_next_alias_opcode (alias
))
1957 DEBUG_TRACE ("try %s", alias
->name
);
1958 assert (alias_opcode_p (alias
) || opcode_has_alias (opcode
));
1960 /* An alias can be a pseudo opcode which will never be used in the
1961 disassembly, e.g. BIC logical immediate is such a pseudo opcode
1963 if (pseudo_opcode_p (alias
))
1965 DEBUG_TRACE ("skip pseudo %s", alias
->name
);
1969 if ((inst
->value
& alias
->mask
) != alias
->opcode
)
1971 DEBUG_TRACE ("skip %s as base opcode not match", alias
->name
);
1974 /* No need to do any complicated transformation on operands, if the alias
1975 opcode does not have any operand. */
1976 if (aarch64_num_of_operands (alias
) == 0 && alias
->opcode
== inst
->value
)
1978 DEBUG_TRACE ("succeed with 0-operand opcode %s", alias
->name
);
1979 aarch64_replace_opcode (inst
, alias
);
1982 if (alias
->flags
& F_CONV
)
1985 memcpy (©
, inst
, sizeof (aarch64_inst
));
1986 /* ALIAS is the preference as long as the instruction can be
1987 successfully converted to the form of ALIAS. */
1988 if (convert_to_alias (©
, alias
) == 1)
1990 aarch64_replace_opcode (©
, alias
);
1991 assert (aarch64_match_operands_constraint (©
, NULL
));
1992 DEBUG_TRACE ("succeed with %s via conversion", alias
->name
);
1993 memcpy (inst
, ©
, sizeof (aarch64_inst
));
1999 /* Directly decode the alias opcode. */
2001 memset (&temp
, '\0', sizeof (aarch64_inst
));
2002 if (aarch64_opcode_decode (alias
, inst
->value
, &temp
, 1) == 1)
2004 DEBUG_TRACE ("succeed with %s via direct decoding", alias
->name
);
2005 memcpy (inst
, &temp
, sizeof (aarch64_inst
));
2012 /* Decode the CODE according to OPCODE; fill INST. Return 0 if the decoding
2013 fails, which meanes that CODE is not an instruction of OPCODE; otherwise
2016 If OPCODE has alias(es) and NOALIASES_P is 0, an alias opcode may be
2017 determined and used to disassemble CODE; this is done just before the
2021 aarch64_opcode_decode (const aarch64_opcode
*opcode
, const aarch64_insn code
,
2022 aarch64_inst
*inst
, int noaliases_p
)
2026 DEBUG_TRACE ("enter with %s", opcode
->name
);
2028 assert (opcode
&& inst
);
2030 /* Check the base opcode. */
2031 if ((code
& opcode
->mask
) != (opcode
->opcode
& opcode
->mask
))
2033 DEBUG_TRACE ("base opcode match FAIL");
2038 memset (inst
, '\0', sizeof (aarch64_inst
));
2040 inst
->opcode
= opcode
;
2043 /* Assign operand codes and indexes. */
2044 for (i
= 0; i
< AARCH64_MAX_OPND_NUM
; ++i
)
2046 if (opcode
->operands
[i
] == AARCH64_OPND_NIL
)
2048 inst
->operands
[i
].type
= opcode
->operands
[i
];
2049 inst
->operands
[i
].idx
= i
;
2052 /* Call the opcode decoder indicated by flags. */
2053 if (opcode_has_special_coder (opcode
) && do_special_decoding (inst
) == 0)
2055 DEBUG_TRACE ("opcode flag-based decoder FAIL");
2059 /* Call operand decoders. */
2060 for (i
= 0; i
< AARCH64_MAX_OPND_NUM
; ++i
)
2062 const aarch64_operand
*opnd
;
2063 enum aarch64_opnd type
;
2065 type
= opcode
->operands
[i
];
2066 if (type
== AARCH64_OPND_NIL
)
2068 opnd
= &aarch64_operands
[type
];
2069 if (operand_has_extractor (opnd
)
2070 && (! aarch64_extract_operand (opnd
, &inst
->operands
[i
], code
, inst
)))
2072 DEBUG_TRACE ("operand decoder FAIL at operand %d", i
);
2077 /* If the opcode has a verifier, then check it now. */
2078 if (opcode
->verifier
&& ! opcode
->verifier (opcode
, code
))
2080 DEBUG_TRACE ("operand verifier FAIL");
2084 /* Match the qualifiers. */
2085 if (aarch64_match_operands_constraint (inst
, NULL
) == 1)
2087 /* Arriving here, the CODE has been determined as a valid instruction
2088 of OPCODE and *INST has been filled with information of this OPCODE
2089 instruction. Before the return, check if the instruction has any
2090 alias and should be disassembled in the form of its alias instead.
2091 If the answer is yes, *INST will be updated. */
2093 determine_disassembling_preference (inst
);
2094 DEBUG_TRACE ("SUCCESS");
2099 DEBUG_TRACE ("constraint matching FAIL");
2106 /* This does some user-friendly fix-up to *INST. It is currently focus on
2107 the adjustment of qualifiers to help the printed instruction
2108 recognized/understood more easily. */
2111 user_friendly_fixup (aarch64_inst
*inst
)
2113 switch (inst
->opcode
->iclass
)
2116 /* TBNZ Xn|Wn, #uimm6, label
2117 Test and Branch Not Zero: conditionally jumps to label if bit number
2118 uimm6 in register Xn is not zero. The bit number implies the width of
2119 the register, which may be written and should be disassembled as Wn if
2120 uimm is less than 32. Limited to a branch offset range of +/- 32KiB.
2122 if (inst
->operands
[1].imm
.value
< 32)
2123 inst
->operands
[0].qualifier
= AARCH64_OPND_QLF_W
;
2129 /* Decode INSN and fill in *INST the instruction information. An alias
2130 opcode may be filled in *INSN if NOALIASES_P is FALSE. Return zero on
2134 aarch64_decode_insn (aarch64_insn insn
, aarch64_inst
*inst
,
2135 bfd_boolean noaliases_p
)
2137 const aarch64_opcode
*opcode
= aarch64_opcode_lookup (insn
);
2139 #ifdef DEBUG_AARCH64
2142 const aarch64_opcode
*tmp
= opcode
;
2144 DEBUG_TRACE ("opcode lookup:");
2147 aarch64_verbose (" %s", tmp
->name
);
2148 tmp
= aarch64_find_next_opcode (tmp
);
2151 #endif /* DEBUG_AARCH64 */
2153 /* A list of opcodes may have been found, as aarch64_opcode_lookup cannot
2154 distinguish some opcodes, e.g. SSHR and MOVI, which almost share the same
2155 opcode field and value, apart from the difference that one of them has an
2156 extra field as part of the opcode, but such a field is used for operand
2157 encoding in other opcode(s) ('immh' in the case of the example). */
2158 while (opcode
!= NULL
)
2160 /* But only one opcode can be decoded successfully for, as the
2161 decoding routine will check the constraint carefully. */
2162 if (aarch64_opcode_decode (opcode
, insn
, inst
, noaliases_p
) == 1)
2164 opcode
= aarch64_find_next_opcode (opcode
);
2170 /* Print operands. */
2173 print_operands (bfd_vma pc
, const aarch64_opcode
*opcode
,
2174 const aarch64_opnd_info
*opnds
, struct disassemble_info
*info
)
2176 int i
, pcrel_p
, num_printed
;
2177 for (i
= 0, num_printed
= 0; i
< AARCH64_MAX_OPND_NUM
; ++i
)
2180 /* We regard the opcode operand info more, however we also look into
2181 the inst->operands to support the disassembling of the optional
2183 The two operand code should be the same in all cases, apart from
2184 when the operand can be optional. */
2185 if (opcode
->operands
[i
] == AARCH64_OPND_NIL
2186 || opnds
[i
].type
== AARCH64_OPND_NIL
)
2189 /* Generate the operand string in STR. */
2190 aarch64_print_operand (str
, sizeof (str
), pc
, opcode
, opnds
, i
, &pcrel_p
,
2193 /* Print the delimiter (taking account of omitted operand(s)). */
2195 (*info
->fprintf_func
) (info
->stream
, "%s",
2196 num_printed
++ == 0 ? "\t" : ", ");
2198 /* Print the operand. */
2200 (*info
->print_address_func
) (info
->target
, info
);
2202 (*info
->fprintf_func
) (info
->stream
, "%s", str
);
2206 /* Print the instruction mnemonic name. */
2209 print_mnemonic_name (const aarch64_inst
*inst
, struct disassemble_info
*info
)
2211 if (inst
->opcode
->flags
& F_COND
)
2213 /* For instructions that are truly conditionally executed, e.g. b.cond,
2214 prepare the full mnemonic name with the corresponding condition
2219 ptr
= strchr (inst
->opcode
->name
, '.');
2220 assert (ptr
&& inst
->cond
);
2221 len
= ptr
- inst
->opcode
->name
;
2223 strncpy (name
, inst
->opcode
->name
, len
);
2225 (*info
->fprintf_func
) (info
->stream
, "%s.%s", name
, inst
->cond
->names
[0]);
2228 (*info
->fprintf_func
) (info
->stream
, "%s", inst
->opcode
->name
);
2231 /* Print the instruction according to *INST. */
2234 print_aarch64_insn (bfd_vma pc
, const aarch64_inst
*inst
,
2235 struct disassemble_info
*info
)
2237 print_mnemonic_name (inst
, info
);
2238 print_operands (pc
, inst
->opcode
, inst
->operands
, info
);
2241 /* Entry-point of the instruction disassembler and printer. */
2244 print_insn_aarch64_word (bfd_vma pc
,
2246 struct disassemble_info
*info
)
2248 static const char *err_msg
[6] =
2251 [-ERR_UND
] = "undefined",
2252 [-ERR_UNP
] = "unpredictable",
2259 info
->insn_info_valid
= 1;
2260 info
->branch_delay_insns
= 0;
2261 info
->data_size
= 0;
2265 if (info
->flags
& INSN_HAS_RELOC
)
2266 /* If the instruction has a reloc associated with it, then
2267 the offset field in the instruction will actually be the
2268 addend for the reloc. (If we are using REL type relocs).
2269 In such cases, we can ignore the pc when computing
2270 addresses, since the addend is not currently pc-relative. */
2273 ret
= aarch64_decode_insn (word
, &inst
, no_aliases
);
2275 if (((word
>> 21) & 0x3ff) == 1)
2277 /* RESERVED for ALES. */
2278 assert (ret
!= ERR_OK
);
2287 /* Handle undefined instructions. */
2288 info
->insn_type
= dis_noninsn
;
2289 (*info
->fprintf_func
) (info
->stream
,".inst\t0x%08x ; %s",
2290 word
, err_msg
[-ret
]);
2293 user_friendly_fixup (&inst
);
2294 print_aarch64_insn (pc
, &inst
, info
);
2301 /* Disallow mapping symbols ($x, $d etc) from
2302 being displayed in symbol relative addresses. */
2305 aarch64_symbol_is_valid (asymbol
* sym
,
2306 struct disassemble_info
* info ATTRIBUTE_UNUSED
)
2313 name
= bfd_asymbol_name (sym
);
2317 || (name
[1] != 'x' && name
[1] != 'd')
2318 || (name
[2] != '\0' && name
[2] != '.'));
2321 /* Print data bytes on INFO->STREAM. */
2324 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED
,
2326 struct disassemble_info
*info
)
2328 switch (info
->bytes_per_chunk
)
2331 info
->fprintf_func (info
->stream
, ".byte\t0x%02x", word
);
2334 info
->fprintf_func (info
->stream
, ".short\t0x%04x", word
);
2337 info
->fprintf_func (info
->stream
, ".word\t0x%08x", word
);
2344 /* Try to infer the code or data type from a symbol.
2345 Returns nonzero if *MAP_TYPE was set. */
2348 get_sym_code_type (struct disassemble_info
*info
, int n
,
2349 enum map_type
*map_type
)
2351 elf_symbol_type
*es
;
2355 es
= *(elf_symbol_type
**)(info
->symtab
+ n
);
2356 type
= ELF_ST_TYPE (es
->internal_elf_sym
.st_info
);
2358 /* If the symbol has function type then use that. */
2359 if (type
== STT_FUNC
)
2361 *map_type
= MAP_INSN
;
2365 /* Check for mapping symbols. */
2366 name
= bfd_asymbol_name(info
->symtab
[n
]);
2368 && (name
[1] == 'x' || name
[1] == 'd')
2369 && (name
[2] == '\0' || name
[2] == '.'))
2371 *map_type
= (name
[1] == 'x' ? MAP_INSN
: MAP_DATA
);
2378 /* Entry-point of the AArch64 disassembler. */
2381 print_insn_aarch64 (bfd_vma pc
,
2382 struct disassemble_info
*info
)
2384 bfd_byte buffer
[INSNLEN
];
2386 void (*printer
) (bfd_vma
, uint32_t, struct disassemble_info
*);
2387 bfd_boolean found
= FALSE
;
2388 unsigned int size
= 4;
2391 if (info
->disassembler_options
)
2393 set_default_aarch64_dis_options (info
);
2395 parse_aarch64_dis_options (info
->disassembler_options
);
2397 /* To avoid repeated parsing of these options, we remove them here. */
2398 info
->disassembler_options
= NULL
;
2401 /* Aarch64 instructions are always little-endian */
2402 info
->endian_code
= BFD_ENDIAN_LITTLE
;
2404 /* First check the full symtab for a mapping symbol, even if there
2405 are no usable non-mapping symbols for this address. */
2406 if (info
->symtab_size
!= 0
2407 && bfd_asymbol_flavour (*info
->symtab
) == bfd_target_elf_flavour
)
2409 enum map_type type
= MAP_INSN
;
2414 if (pc
<= last_mapping_addr
)
2415 last_mapping_sym
= -1;
2417 /* Start scanning at the start of the function, or wherever
2418 we finished last time. */
2419 n
= info
->symtab_pos
+ 1;
2420 if (n
< last_mapping_sym
)
2421 n
= last_mapping_sym
;
2423 /* Scan up to the location being disassembled. */
2424 for (; n
< info
->symtab_size
; n
++)
2426 addr
= bfd_asymbol_value (info
->symtab
[n
]);
2429 if ((info
->section
== NULL
2430 || info
->section
== info
->symtab
[n
]->section
)
2431 && get_sym_code_type (info
, n
, &type
))
2440 n
= info
->symtab_pos
;
2441 if (n
< last_mapping_sym
)
2442 n
= last_mapping_sym
;
2444 /* No mapping symbol found at this address. Look backwards
2445 for a preceeding one. */
2448 if (get_sym_code_type (info
, n
, &type
))
2457 last_mapping_sym
= last_sym
;
2460 /* Look a little bit ahead to see if we should print out
2461 less than four bytes of data. If there's a symbol,
2462 mapping or otherwise, after two bytes then don't
2464 if (last_type
== MAP_DATA
)
2466 size
= 4 - (pc
& 3);
2467 for (n
= last_sym
+ 1; n
< info
->symtab_size
; n
++)
2469 addr
= bfd_asymbol_value (info
->symtab
[n
]);
2472 if (addr
- pc
< size
)
2477 /* If the next symbol is after three bytes, we need to
2478 print only part of the data, so that we can use either
2481 size
= (pc
& 1) ? 1 : 2;
2485 if (last_type
== MAP_DATA
)
2487 /* size was set above. */
2488 info
->bytes_per_chunk
= size
;
2489 info
->display_endian
= info
->endian
;
2490 printer
= print_insn_data
;
2494 info
->bytes_per_chunk
= size
= INSNLEN
;
2495 info
->display_endian
= info
->endian_code
;
2496 printer
= print_insn_aarch64_word
;
2499 status
= (*info
->read_memory_func
) (pc
, buffer
, size
, info
);
2502 (*info
->memory_error_func
) (status
, pc
, info
);
2506 data
= bfd_get_bits (buffer
, size
* 8,
2507 info
->display_endian
== BFD_ENDIAN_BIG
);
2509 (*printer
) (pc
, data
, info
);
2515 print_aarch64_disassembler_options (FILE *stream
)
2517 fprintf (stream
, _("\n\
2518 The following AARCH64 specific disassembler options are supported for use\n\
2519 with the -M switch (multiple options should be separated by commas):\n"));
2521 fprintf (stream
, _("\n\
2522 no-aliases Don't print instruction aliases.\n"));
2524 fprintf (stream
, _("\n\
2525 aliases Do print instruction aliases.\n"));
2527 #ifdef DEBUG_AARCH64
2528 fprintf (stream
, _("\n\
2529 debug_dump Temp switch for debug trace.\n"));
2530 #endif /* DEBUG_AARCH64 */
2532 fprintf (stream
, _("\n"));