1 /* aarch64-opc.c -- AArch64 opcode support.
2 Copyright (C) 2009-2017 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/>. */
30 #include "libiberty.h"
32 #include "aarch64-opc.h"
35 int debug_dump = FALSE;
36 #endif /* DEBUG_AARCH64 */
38 /* The enumeration strings associated with each value of a 5-bit SVE
39 pattern operand. A null entry indicates a reserved meaning. */
40 const char *const aarch64_sve_pattern_array[32] = {
79 /* The enumeration strings associated with each value of a 4-bit SVE
80 prefetch operand. A null entry indicates a reserved meaning. */
81 const char *const aarch64_sve_prfop_array[16] = {
102 /* Helper functions to determine which operand to be used to encode/decode
103 the size:Q fields for AdvSIMD instructions. */
105 static inline bfd_boolean
106 vector_qualifier_p (enum aarch64_opnd_qualifier qualifier)
108 return ((qualifier >= AARCH64_OPND_QLF_V_8B
109 && qualifier <= AARCH64_OPND_QLF_V_1Q) ? TRUE
113 static inline bfd_boolean
114 fp_qualifier_p (enum aarch64_opnd_qualifier qualifier)
116 return ((qualifier >= AARCH64_OPND_QLF_S_B
117 && qualifier <= AARCH64_OPND_QLF_S_Q) ? TRUE
127 DP_VECTOR_ACROSS_LANES,
130 static const char significant_operand_index [] =
132 0, /* DP_UNKNOWN, by default using operand 0. */
133 0, /* DP_VECTOR_3SAME */
134 1, /* DP_VECTOR_LONG */
135 2, /* DP_VECTOR_WIDE */
136 1, /* DP_VECTOR_ACROSS_LANES */
139 /* Given a sequence of qualifiers in QUALIFIERS, determine and return
141 N.B. QUALIFIERS is a possible sequence of qualifiers each of which
142 corresponds to one of a sequence of operands. */
144 static enum data_pattern
145 get_data_pattern (const aarch64_opnd_qualifier_seq_t qualifiers)
147 if (vector_qualifier_p (qualifiers[0]) == TRUE)
149 /* e.g. v.4s, v.4s, v.4s
150 or v.4h, v.4h, v.h[3]. */
151 if (qualifiers[0] == qualifiers[1]
152 && vector_qualifier_p (qualifiers[2]) == TRUE
153 && (aarch64_get_qualifier_esize (qualifiers[0])
154 == aarch64_get_qualifier_esize (qualifiers[1]))
155 && (aarch64_get_qualifier_esize (qualifiers[0])
156 == aarch64_get_qualifier_esize (qualifiers[2])))
157 return DP_VECTOR_3SAME;
158 /* e.g. v.8h, v.8b, v.8b.
159 or v.4s, v.4h, v.h[2].
161 if (vector_qualifier_p (qualifiers[1]) == TRUE
162 && aarch64_get_qualifier_esize (qualifiers[0]) != 0
163 && (aarch64_get_qualifier_esize (qualifiers[0])
164 == aarch64_get_qualifier_esize (qualifiers[1]) << 1))
165 return DP_VECTOR_LONG;
166 /* e.g. v.8h, v.8h, v.8b. */
167 if (qualifiers[0] == qualifiers[1]
168 && vector_qualifier_p (qualifiers[2]) == TRUE
169 && aarch64_get_qualifier_esize (qualifiers[0]) != 0
170 && (aarch64_get_qualifier_esize (qualifiers[0])
171 == aarch64_get_qualifier_esize (qualifiers[2]) << 1)
172 && (aarch64_get_qualifier_esize (qualifiers[0])
173 == aarch64_get_qualifier_esize (qualifiers[1])))
174 return DP_VECTOR_WIDE;
176 else if (fp_qualifier_p (qualifiers[0]) == TRUE)
178 /* e.g. SADDLV <V><d>, <Vn>.<T>. */
179 if (vector_qualifier_p (qualifiers[1]) == TRUE
180 && qualifiers[2] == AARCH64_OPND_QLF_NIL)
181 return DP_VECTOR_ACROSS_LANES;
187 /* Select the operand to do the encoding/decoding of the 'size:Q' fields in
188 the AdvSIMD instructions. */
189 /* N.B. it is possible to do some optimization that doesn't call
190 get_data_pattern each time when we need to select an operand. We can
191 either buffer the caculated the result or statically generate the data,
192 however, it is not obvious that the optimization will bring significant
196 aarch64_select_operand_for_sizeq_field_coding (const aarch64_opcode *opcode)
199 significant_operand_index [get_data_pattern (opcode->qualifiers_list[0])];
202 const aarch64_field fields[] =
205 { 0, 4 }, /* cond2: condition in truly conditional-executed inst. */
206 { 0, 4 }, /* nzcv: flag bit specifier, encoded in the "nzcv" field. */
207 { 5, 5 }, /* defgh: d:e:f:g:h bits in AdvSIMD modified immediate. */
208 { 16, 3 }, /* abc: a:b:c bits in AdvSIMD modified immediate. */
209 { 5, 19 }, /* imm19: e.g. in CBZ. */
210 { 5, 19 }, /* immhi: e.g. in ADRP. */
211 { 29, 2 }, /* immlo: e.g. in ADRP. */
212 { 22, 2 }, /* size: in most AdvSIMD and floating-point instructions. */
213 { 10, 2 }, /* vldst_size: size field in the AdvSIMD load/store inst. */
214 { 29, 1 }, /* op: in AdvSIMD modified immediate instructions. */
215 { 30, 1 }, /* Q: in most AdvSIMD instructions. */
216 { 0, 5 }, /* Rt: in load/store instructions. */
217 { 0, 5 }, /* Rd: in many integer instructions. */
218 { 5, 5 }, /* Rn: in many integer instructions. */
219 { 10, 5 }, /* Rt2: in load/store pair instructions. */
220 { 10, 5 }, /* Ra: in fp instructions. */
221 { 5, 3 }, /* op2: in the system instructions. */
222 { 8, 4 }, /* CRm: in the system instructions. */
223 { 12, 4 }, /* CRn: in the system instructions. */
224 { 16, 3 }, /* op1: in the system instructions. */
225 { 19, 2 }, /* op0: in the system instructions. */
226 { 10, 3 }, /* imm3: in add/sub extended reg instructions. */
227 { 12, 4 }, /* cond: condition flags as a source operand. */
228 { 12, 4 }, /* opcode: in advsimd load/store instructions. */
229 { 12, 4 }, /* cmode: in advsimd modified immediate instructions. */
230 { 13, 3 }, /* asisdlso_opcode: opcode in advsimd ld/st single element. */
231 { 13, 2 }, /* len: in advsimd tbl/tbx instructions. */
232 { 16, 5 }, /* Rm: in ld/st reg offset and some integer inst. */
233 { 16, 5 }, /* Rs: in load/store exclusive instructions. */
234 { 13, 3 }, /* option: in ld/st reg offset + add/sub extended reg inst. */
235 { 12, 1 }, /* S: in load/store reg offset instructions. */
236 { 21, 2 }, /* hw: in move wide constant instructions. */
237 { 22, 2 }, /* opc: in load/store reg offset instructions. */
238 { 23, 1 }, /* opc1: in load/store reg offset instructions. */
239 { 22, 2 }, /* shift: in add/sub reg/imm shifted instructions. */
240 { 22, 2 }, /* type: floating point type field in fp data inst. */
241 { 30, 2 }, /* ldst_size: size field in ld/st reg offset inst. */
242 { 10, 6 }, /* imm6: in add/sub reg shifted instructions. */
243 { 11, 4 }, /* imm4: in advsimd ext and advsimd ins instructions. */
244 { 16, 5 }, /* imm5: in conditional compare (immediate) instructions. */
245 { 15, 7 }, /* imm7: in load/store pair pre/post index instructions. */
246 { 13, 8 }, /* imm8: in floating-point scalar move immediate inst. */
247 { 12, 9 }, /* imm9: in load/store pre/post index instructions. */
248 { 10, 12 }, /* imm12: in ld/st unsigned imm or add/sub shifted inst. */
249 { 5, 14 }, /* imm14: in test bit and branch instructions. */
250 { 5, 16 }, /* imm16: in exception instructions. */
251 { 0, 26 }, /* imm26: in unconditional branch instructions. */
252 { 10, 6 }, /* imms: in bitfield and logical immediate instructions. */
253 { 16, 6 }, /* immr: in bitfield and logical immediate instructions. */
254 { 16, 3 }, /* immb: in advsimd shift by immediate instructions. */
255 { 19, 4 }, /* immh: in advsimd shift by immediate instructions. */
256 { 22, 1 }, /* S: in LDRAA and LDRAB instructions. */
257 { 22, 1 }, /* N: in logical (immediate) instructions. */
258 { 11, 1 }, /* index: in ld/st inst deciding the pre/post-index. */
259 { 24, 1 }, /* index2: in ld/st pair inst deciding the pre/post-index. */
260 { 31, 1 }, /* sf: in integer data processing instructions. */
261 { 30, 1 }, /* lse_size: in LSE extension atomic instructions. */
262 { 11, 1 }, /* H: in advsimd scalar x indexed element instructions. */
263 { 21, 1 }, /* L: in advsimd scalar x indexed element instructions. */
264 { 20, 1 }, /* M: in advsimd scalar x indexed element instructions. */
265 { 31, 1 }, /* b5: in the test bit and branch instructions. */
266 { 19, 5 }, /* b40: in the test bit and branch instructions. */
267 { 10, 6 }, /* scale: in the fixed-point scalar to fp converting inst. */
268 { 4, 1 }, /* SVE_M_4: Merge/zero select, bit 4. */
269 { 14, 1 }, /* SVE_M_14: Merge/zero select, bit 14. */
270 { 16, 1 }, /* SVE_M_16: Merge/zero select, bit 16. */
271 { 17, 1 }, /* SVE_N: SVE equivalent of N. */
272 { 0, 4 }, /* SVE_Pd: p0-p15, bits [3,0]. */
273 { 10, 3 }, /* SVE_Pg3: p0-p7, bits [12,10]. */
274 { 5, 4 }, /* SVE_Pg4_5: p0-p15, bits [8,5]. */
275 { 10, 4 }, /* SVE_Pg4_10: p0-p15, bits [13,10]. */
276 { 16, 4 }, /* SVE_Pg4_16: p0-p15, bits [19,16]. */
277 { 16, 4 }, /* SVE_Pm: p0-p15, bits [19,16]. */
278 { 5, 4 }, /* SVE_Pn: p0-p15, bits [8,5]. */
279 { 0, 4 }, /* SVE_Pt: p0-p15, bits [3,0]. */
280 { 5, 5 }, /* SVE_Rm: SVE alternative position for Rm. */
281 { 16, 5 }, /* SVE_Rn: SVE alternative position for Rn. */
282 { 0, 5 }, /* SVE_Vd: Scalar SIMD&FP register, bits [4,0]. */
283 { 5, 5 }, /* SVE_Vm: Scalar SIMD&FP register, bits [9,5]. */
284 { 5, 5 }, /* SVE_Vn: Scalar SIMD&FP register, bits [9,5]. */
285 { 5, 5 }, /* SVE_Za_5: SVE vector register, bits [9,5]. */
286 { 16, 5 }, /* SVE_Za_16: SVE vector register, bits [20,16]. */
287 { 0, 5 }, /* SVE_Zd: SVE vector register. bits [4,0]. */
288 { 5, 5 }, /* SVE_Zm_5: SVE vector register, bits [9,5]. */
289 { 16, 5 }, /* SVE_Zm_16: SVE vector register, bits [20,16]. */
290 { 5, 5 }, /* SVE_Zn: SVE vector register, bits [9,5]. */
291 { 0, 5 }, /* SVE_Zt: SVE vector register, bits [4,0]. */
292 { 5, 1 }, /* SVE_i1: single-bit immediate. */
293 { 22, 1 }, /* SVE_i3h: high bit of 3-bit immediate. */
294 { 16, 3 }, /* SVE_imm3: 3-bit immediate field. */
295 { 16, 4 }, /* SVE_imm4: 4-bit immediate field. */
296 { 5, 5 }, /* SVE_imm5: 5-bit immediate field. */
297 { 16, 5 }, /* SVE_imm5b: secondary 5-bit immediate field. */
298 { 16, 6 }, /* SVE_imm6: 6-bit immediate field. */
299 { 14, 7 }, /* SVE_imm7: 7-bit immediate field. */
300 { 5, 8 }, /* SVE_imm8: 8-bit immediate field. */
301 { 5, 9 }, /* SVE_imm9: 9-bit immediate field. */
302 { 11, 6 }, /* SVE_immr: SVE equivalent of immr. */
303 { 5, 6 }, /* SVE_imms: SVE equivalent of imms. */
304 { 10, 2 }, /* SVE_msz: 2-bit shift amount for ADR. */
305 { 5, 5 }, /* SVE_pattern: vector pattern enumeration. */
306 { 0, 4 }, /* SVE_prfop: prefetch operation for SVE PRF[BHWD]. */
307 { 16, 1 }, /* SVE_rot1: 1-bit rotation amount. */
308 { 10, 2 }, /* SVE_rot2: 2-bit rotation amount. */
309 { 22, 1 }, /* SVE_sz: 1-bit element size select. */
310 { 16, 4 }, /* SVE_tsz: triangular size select. */
311 { 22, 2 }, /* SVE_tszh: triangular size select high, bits [23,22]. */
312 { 8, 2 }, /* SVE_tszl_8: triangular size select low, bits [9,8]. */
313 { 19, 2 }, /* SVE_tszl_19: triangular size select low, bits [20,19]. */
314 { 14, 1 }, /* SVE_xs_14: UXTW/SXTW select (bit 14). */
315 { 22, 1 }, /* SVE_xs_22: UXTW/SXTW select (bit 22). */
316 { 11, 2 }, /* rotate1: FCMLA immediate rotate. */
317 { 13, 2 }, /* rotate2: Indexed element FCMLA immediate rotate. */
318 { 12, 1 }, /* rotate3: FCADD immediate rotate. */
321 enum aarch64_operand_class
322 aarch64_get_operand_class (enum aarch64_opnd type)
324 return aarch64_operands[type].op_class;
328 aarch64_get_operand_name (enum aarch64_opnd type)
330 return aarch64_operands[type].name;
333 /* Get operand description string.
334 This is usually for the diagnosis purpose. */
336 aarch64_get_operand_desc (enum aarch64_opnd type)
338 return aarch64_operands[type].desc;
341 /* Table of all conditional affixes. */
342 const aarch64_cond aarch64_conds[16] =
344 {{"eq", "none"}, 0x0},
345 {{"ne", "any"}, 0x1},
346 {{"cs", "hs", "nlast"}, 0x2},
347 {{"cc", "lo", "ul", "last"}, 0x3},
348 {{"mi", "first"}, 0x4},
349 {{"pl", "nfrst"}, 0x5},
352 {{"hi", "pmore"}, 0x8},
353 {{"ls", "plast"}, 0x9},
354 {{"ge", "tcont"}, 0xa},
355 {{"lt", "tstop"}, 0xb},
363 get_cond_from_value (aarch64_insn value)
366 return &aarch64_conds[(unsigned int) value];
370 get_inverted_cond (const aarch64_cond *cond)
372 return &aarch64_conds[cond->value ^ 0x1];
375 /* Table describing the operand extension/shifting operators; indexed by
376 enum aarch64_modifier_kind.
378 The value column provides the most common values for encoding modifiers,
379 which enables table-driven encoding/decoding for the modifiers. */
380 const struct aarch64_name_value_pair aarch64_operand_modifiers [] =
401 enum aarch64_modifier_kind
402 aarch64_get_operand_modifier (const struct aarch64_name_value_pair *desc)
404 return desc - aarch64_operand_modifiers;
408 aarch64_get_operand_modifier_value (enum aarch64_modifier_kind kind)
410 return aarch64_operand_modifiers[kind].value;
413 enum aarch64_modifier_kind
414 aarch64_get_operand_modifier_from_value (aarch64_insn value,
415 bfd_boolean extend_p)
417 if (extend_p == TRUE)
418 return AARCH64_MOD_UXTB + value;
420 return AARCH64_MOD_LSL - value;
424 aarch64_extend_operator_p (enum aarch64_modifier_kind kind)
426 return (kind > AARCH64_MOD_LSL && kind <= AARCH64_MOD_SXTX)
430 static inline bfd_boolean
431 aarch64_shift_operator_p (enum aarch64_modifier_kind kind)
433 return (kind >= AARCH64_MOD_ROR && kind <= AARCH64_MOD_LSL)
437 const struct aarch64_name_value_pair aarch64_barrier_options[16] =
457 /* Table describing the operands supported by the aliases of the HINT
460 The name column is the operand that is accepted for the alias. The value
461 column is the hint number of the alias. The list of operands is terminated
462 by NULL in the name column. */
464 const struct aarch64_name_value_pair aarch64_hint_options[] =
466 { "csync", 0x11 }, /* PSB CSYNC. */
470 /* op -> op: load = 0 instruction = 1 store = 2
472 t -> temporal: temporal (retained) = 0 non-temporal (streaming) = 1 */
473 #define B(op,l,t) (((op) << 3) | (((l) - 1) << 1) | (t))
474 const struct aarch64_name_value_pair aarch64_prfops[32] =
476 { "pldl1keep", B(0, 1, 0) },
477 { "pldl1strm", B(0, 1, 1) },
478 { "pldl2keep", B(0, 2, 0) },
479 { "pldl2strm", B(0, 2, 1) },
480 { "pldl3keep", B(0, 3, 0) },
481 { "pldl3strm", B(0, 3, 1) },
484 { "plil1keep", B(1, 1, 0) },
485 { "plil1strm", B(1, 1, 1) },
486 { "plil2keep", B(1, 2, 0) },
487 { "plil2strm", B(1, 2, 1) },
488 { "plil3keep", B(1, 3, 0) },
489 { "plil3strm", B(1, 3, 1) },
492 { "pstl1keep", B(2, 1, 0) },
493 { "pstl1strm", B(2, 1, 1) },
494 { "pstl2keep", B(2, 2, 0) },
495 { "pstl2strm", B(2, 2, 1) },
496 { "pstl3keep", B(2, 3, 0) },
497 { "pstl3strm", B(2, 3, 1) },
511 /* Utilities on value constraint. */
514 value_in_range_p (int64_t value, int low, int high)
516 return (value >= low && value <= high) ? 1 : 0;
519 /* Return true if VALUE is a multiple of ALIGN. */
521 value_aligned_p (int64_t value, int align)
523 return (value % align) == 0;
526 /* A signed value fits in a field. */
528 value_fit_signed_field_p (int64_t value, unsigned width)
531 if (width < sizeof (value) * 8)
533 int64_t lim = (int64_t)1 << (width - 1);
534 if (value >= -lim && value < lim)
540 /* An unsigned value fits in a field. */
542 value_fit_unsigned_field_p (int64_t value, unsigned width)
545 if (width < sizeof (value) * 8)
547 int64_t lim = (int64_t)1 << width;
548 if (value >= 0 && value < lim)
554 /* Return 1 if OPERAND is SP or WSP. */
556 aarch64_stack_pointer_p (const aarch64_opnd_info *operand)
558 return ((aarch64_get_operand_class (operand->type)
559 == AARCH64_OPND_CLASS_INT_REG)
560 && operand_maybe_stack_pointer (aarch64_operands + operand->type)
561 && operand->reg.regno == 31);
564 /* Return 1 if OPERAND is XZR or WZP. */
566 aarch64_zero_register_p (const aarch64_opnd_info *operand)
568 return ((aarch64_get_operand_class (operand->type)
569 == AARCH64_OPND_CLASS_INT_REG)
570 && !operand_maybe_stack_pointer (aarch64_operands + operand->type)
571 && operand->reg.regno == 31);
574 /* Return true if the operand *OPERAND that has the operand code
575 OPERAND->TYPE and been qualified by OPERAND->QUALIFIER can be also
576 qualified by the qualifier TARGET. */
579 operand_also_qualified_p (const struct aarch64_opnd_info *operand,
580 aarch64_opnd_qualifier_t target)
582 switch (operand->qualifier)
584 case AARCH64_OPND_QLF_W:
585 if (target == AARCH64_OPND_QLF_WSP && aarch64_stack_pointer_p (operand))
588 case AARCH64_OPND_QLF_X:
589 if (target == AARCH64_OPND_QLF_SP && aarch64_stack_pointer_p (operand))
592 case AARCH64_OPND_QLF_WSP:
593 if (target == AARCH64_OPND_QLF_W
594 && operand_maybe_stack_pointer (aarch64_operands + operand->type))
597 case AARCH64_OPND_QLF_SP:
598 if (target == AARCH64_OPND_QLF_X
599 && operand_maybe_stack_pointer (aarch64_operands + operand->type))
609 /* Given qualifier sequence list QSEQ_LIST and the known qualifier KNOWN_QLF
610 for operand KNOWN_IDX, return the expected qualifier for operand IDX.
612 Return NIL if more than one expected qualifiers are found. */
614 aarch64_opnd_qualifier_t
615 aarch64_get_expected_qualifier (const aarch64_opnd_qualifier_seq_t *qseq_list,
617 const aarch64_opnd_qualifier_t known_qlf,
624 When the known qualifier is NIL, we have to assume that there is only
625 one qualifier sequence in the *QSEQ_LIST and return the corresponding
626 qualifier directly. One scenario is that for instruction
627 PRFM <prfop>, [<Xn|SP>, #:lo12:<symbol>]
628 which has only one possible valid qualifier sequence
630 the caller may pass NIL in KNOWN_QLF to obtain S_D so that it can
631 determine the correct relocation type (i.e. LDST64_LO12) for PRFM.
633 Because the qualifier NIL has dual roles in the qualifier sequence:
634 it can mean no qualifier for the operand, or the qualifer sequence is
635 not in use (when all qualifiers in the sequence are NILs), we have to
636 handle this special case here. */
637 if (known_qlf == AARCH64_OPND_NIL)
639 assert (qseq_list[0][known_idx] == AARCH64_OPND_NIL);
640 return qseq_list[0][idx];
643 for (i = 0, saved_i = -1; i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
645 if (qseq_list[i][known_idx] == known_qlf)
648 /* More than one sequences are found to have KNOWN_QLF at
650 return AARCH64_OPND_NIL;
655 return qseq_list[saved_i][idx];
658 enum operand_qualifier_kind
666 /* Operand qualifier description. */
667 struct operand_qualifier_data
669 /* The usage of the three data fields depends on the qualifier kind. */
676 enum operand_qualifier_kind kind;
679 /* Indexed by the operand qualifier enumerators. */
680 struct operand_qualifier_data aarch64_opnd_qualifiers[] =
682 {0, 0, 0, "NIL", OQK_NIL},
684 /* Operand variant qualifiers.
686 element size, number of elements and common value for encoding. */
688 {4, 1, 0x0, "w", OQK_OPD_VARIANT},
689 {8, 1, 0x1, "x", OQK_OPD_VARIANT},
690 {4, 1, 0x0, "wsp", OQK_OPD_VARIANT},
691 {8, 1, 0x1, "sp", OQK_OPD_VARIANT},
693 {1, 1, 0x0, "b", OQK_OPD_VARIANT},
694 {2, 1, 0x1, "h", OQK_OPD_VARIANT},
695 {4, 1, 0x2, "s", OQK_OPD_VARIANT},
696 {8, 1, 0x3, "d", OQK_OPD_VARIANT},
697 {16, 1, 0x4, "q", OQK_OPD_VARIANT},
699 {1, 8, 0x0, "8b", OQK_OPD_VARIANT},
700 {1, 16, 0x1, "16b", OQK_OPD_VARIANT},
701 {2, 2, 0x0, "2h", OQK_OPD_VARIANT},
702 {2, 4, 0x2, "4h", OQK_OPD_VARIANT},
703 {2, 8, 0x3, "8h", OQK_OPD_VARIANT},
704 {4, 2, 0x4, "2s", OQK_OPD_VARIANT},
705 {4, 4, 0x5, "4s", OQK_OPD_VARIANT},
706 {8, 1, 0x6, "1d", OQK_OPD_VARIANT},
707 {8, 2, 0x7, "2d", OQK_OPD_VARIANT},
708 {16, 1, 0x8, "1q", OQK_OPD_VARIANT},
710 {0, 0, 0, "z", OQK_OPD_VARIANT},
711 {0, 0, 0, "m", OQK_OPD_VARIANT},
713 /* Qualifiers constraining the value range.
715 Lower bound, higher bound, unused. */
717 {0, 15, 0, "CR", OQK_VALUE_IN_RANGE},
718 {0, 7, 0, "imm_0_7" , OQK_VALUE_IN_RANGE},
719 {0, 15, 0, "imm_0_15", OQK_VALUE_IN_RANGE},
720 {0, 31, 0, "imm_0_31", OQK_VALUE_IN_RANGE},
721 {0, 63, 0, "imm_0_63", OQK_VALUE_IN_RANGE},
722 {1, 32, 0, "imm_1_32", OQK_VALUE_IN_RANGE},
723 {1, 64, 0, "imm_1_64", OQK_VALUE_IN_RANGE},
725 /* Qualifiers for miscellaneous purpose.
727 unused, unused and unused. */
732 {0, 0, 0, "retrieving", 0},
735 static inline bfd_boolean
736 operand_variant_qualifier_p (aarch64_opnd_qualifier_t qualifier)
738 return (aarch64_opnd_qualifiers[qualifier].kind == OQK_OPD_VARIANT)
742 static inline bfd_boolean
743 qualifier_value_in_range_constraint_p (aarch64_opnd_qualifier_t qualifier)
745 return (aarch64_opnd_qualifiers[qualifier].kind == OQK_VALUE_IN_RANGE)
750 aarch64_get_qualifier_name (aarch64_opnd_qualifier_t qualifier)
752 return aarch64_opnd_qualifiers[qualifier].desc;
755 /* Given an operand qualifier, return the expected data element size
756 of a qualified operand. */
758 aarch64_get_qualifier_esize (aarch64_opnd_qualifier_t qualifier)
760 assert (operand_variant_qualifier_p (qualifier) == TRUE);
761 return aarch64_opnd_qualifiers[qualifier].data0;
765 aarch64_get_qualifier_nelem (aarch64_opnd_qualifier_t qualifier)
767 assert (operand_variant_qualifier_p (qualifier) == TRUE);
768 return aarch64_opnd_qualifiers[qualifier].data1;
772 aarch64_get_qualifier_standard_value (aarch64_opnd_qualifier_t qualifier)
774 assert (operand_variant_qualifier_p (qualifier) == TRUE);
775 return aarch64_opnd_qualifiers[qualifier].data2;
779 get_lower_bound (aarch64_opnd_qualifier_t qualifier)
781 assert (qualifier_value_in_range_constraint_p (qualifier) == TRUE);
782 return aarch64_opnd_qualifiers[qualifier].data0;
786 get_upper_bound (aarch64_opnd_qualifier_t qualifier)
788 assert (qualifier_value_in_range_constraint_p (qualifier) == TRUE);
789 return aarch64_opnd_qualifiers[qualifier].data1;
794 aarch64_verbose (const char *str, ...)
805 dump_qualifier_sequence (const aarch64_opnd_qualifier_t *qualifier)
809 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i, ++qualifier)
810 printf ("%s,", aarch64_get_qualifier_name (*qualifier));
815 dump_match_qualifiers (const struct aarch64_opnd_info *opnd,
816 const aarch64_opnd_qualifier_t *qualifier)
819 aarch64_opnd_qualifier_t curr[AARCH64_MAX_OPND_NUM];
821 aarch64_verbose ("dump_match_qualifiers:");
822 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
823 curr[i] = opnd[i].qualifier;
824 dump_qualifier_sequence (curr);
825 aarch64_verbose ("against");
826 dump_qualifier_sequence (qualifier);
828 #endif /* DEBUG_AARCH64 */
830 /* TODO improve this, we can have an extra field at the runtime to
831 store the number of operands rather than calculating it every time. */
834 aarch64_num_of_operands (const aarch64_opcode *opcode)
837 const enum aarch64_opnd *opnds = opcode->operands;
838 while (opnds[i++] != AARCH64_OPND_NIL)
841 assert (i >= 0 && i <= AARCH64_MAX_OPND_NUM);
845 /* Find the best matched qualifier sequence in *QUALIFIERS_LIST for INST.
846 If succeeds, fill the found sequence in *RET, return 1; otherwise return 0.
848 N.B. on the entry, it is very likely that only some operands in *INST
849 have had their qualifiers been established.
851 If STOP_AT is not -1, the function will only try to match
852 the qualifier sequence for operands before and including the operand
853 of index STOP_AT; and on success *RET will only be filled with the first
854 (STOP_AT+1) qualifiers.
856 A couple examples of the matching algorithm:
864 Apart from serving the main encoding routine, this can also be called
865 during or after the operand decoding. */
868 aarch64_find_best_match (const aarch64_inst *inst,
869 const aarch64_opnd_qualifier_seq_t *qualifiers_list,
870 int stop_at, aarch64_opnd_qualifier_t *ret)
874 const aarch64_opnd_qualifier_t *qualifiers;
876 num_opnds = aarch64_num_of_operands (inst->opcode);
879 DEBUG_TRACE ("SUCCEED: no operand");
883 if (stop_at < 0 || stop_at >= num_opnds)
884 stop_at = num_opnds - 1;
886 /* For each pattern. */
887 for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i, ++qualifiers_list)
890 qualifiers = *qualifiers_list;
892 /* Start as positive. */
895 DEBUG_TRACE ("%d", i);
898 dump_match_qualifiers (inst->operands, qualifiers);
901 /* Most opcodes has much fewer patterns in the list.
902 First NIL qualifier indicates the end in the list. */
903 if (empty_qualifier_sequence_p (qualifiers) == TRUE)
905 DEBUG_TRACE_IF (i == 0, "SUCCEED: empty qualifier list");
911 for (j = 0; j < num_opnds && j <= stop_at; ++j, ++qualifiers)
913 if (inst->operands[j].qualifier == AARCH64_OPND_QLF_NIL)
915 /* Either the operand does not have qualifier, or the qualifier
916 for the operand needs to be deduced from the qualifier
918 In the latter case, any constraint checking related with
919 the obtained qualifier should be done later in
920 operand_general_constraint_met_p. */
923 else if (*qualifiers != inst->operands[j].qualifier)
925 /* Unless the target qualifier can also qualify the operand
926 (which has already had a non-nil qualifier), non-equal
927 qualifiers are generally un-matched. */
928 if (operand_also_qualified_p (inst->operands + j, *qualifiers))
937 continue; /* Equal qualifiers are certainly matched. */
940 /* Qualifiers established. */
947 /* Fill the result in *RET. */
949 qualifiers = *qualifiers_list;
951 DEBUG_TRACE ("complete qualifiers using list %d", i);
954 dump_qualifier_sequence (qualifiers);
957 for (j = 0; j <= stop_at; ++j, ++qualifiers)
958 ret[j] = *qualifiers;
959 for (; j < AARCH64_MAX_OPND_NUM; ++j)
960 ret[j] = AARCH64_OPND_QLF_NIL;
962 DEBUG_TRACE ("SUCCESS");
966 DEBUG_TRACE ("FAIL");
970 /* Operand qualifier matching and resolving.
972 Return 1 if the operand qualifier(s) in *INST match one of the qualifier
973 sequences in INST->OPCODE->qualifiers_list; otherwise return 0.
975 if UPDATE_P == TRUE, update the qualifier(s) in *INST after the matching
979 match_operands_qualifier (aarch64_inst *inst, bfd_boolean update_p)
982 aarch64_opnd_qualifier_seq_t qualifiers;
984 if (!aarch64_find_best_match (inst, inst->opcode->qualifiers_list, -1,
987 DEBUG_TRACE ("matching FAIL");
991 if (inst->opcode->flags & F_STRICT)
993 /* Require an exact qualifier match, even for NIL qualifiers. */
994 nops = aarch64_num_of_operands (inst->opcode);
995 for (i = 0; i < nops; ++i)
996 if (inst->operands[i].qualifier != qualifiers[i])
1000 /* Update the qualifiers. */
1001 if (update_p == TRUE)
1002 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
1004 if (inst->opcode->operands[i] == AARCH64_OPND_NIL)
1006 DEBUG_TRACE_IF (inst->operands[i].qualifier != qualifiers[i],
1007 "update %s with %s for operand %d",
1008 aarch64_get_qualifier_name (inst->operands[i].qualifier),
1009 aarch64_get_qualifier_name (qualifiers[i]), i);
1010 inst->operands[i].qualifier = qualifiers[i];
1013 DEBUG_TRACE ("matching SUCCESS");
1017 /* Return TRUE if VALUE is a wide constant that can be moved into a general
1020 IS32 indicates whether value is a 32-bit immediate or not.
1021 If SHIFT_AMOUNT is not NULL, on the return of TRUE, the logical left shift
1022 amount will be returned in *SHIFT_AMOUNT. */
1025 aarch64_wide_constant_p (int64_t value, int is32, unsigned int *shift_amount)
1029 DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 ")", value, value);
1033 /* Allow all zeros or all ones in top 32-bits, so that
1034 32-bit constant expressions like ~0x80000000 are
1036 uint64_t ext = value;
1037 if (ext >> 32 != 0 && ext >> 32 != (uint64_t) 0xffffffff)
1038 /* Immediate out of range. */
1040 value &= (int64_t) 0xffffffff;
1043 /* first, try movz then movn */
1045 if ((value & ((int64_t) 0xffff << 0)) == value)
1047 else if ((value & ((int64_t) 0xffff << 16)) == value)
1049 else if (!is32 && (value & ((int64_t) 0xffff << 32)) == value)
1051 else if (!is32 && (value & ((int64_t) 0xffff << 48)) == value)
1056 DEBUG_TRACE ("exit FALSE with 0x%" PRIx64 "(%" PRIi64 ")", value, value);
1060 if (shift_amount != NULL)
1061 *shift_amount = amount;
1063 DEBUG_TRACE ("exit TRUE with amount %d", amount);
1068 /* Build the accepted values for immediate logical SIMD instructions.
1070 The standard encodings of the immediate value are:
1071 N imms immr SIMD size R S
1072 1 ssssss rrrrrr 64 UInt(rrrrrr) UInt(ssssss)
1073 0 0sssss 0rrrrr 32 UInt(rrrrr) UInt(sssss)
1074 0 10ssss 00rrrr 16 UInt(rrrr) UInt(ssss)
1075 0 110sss 000rrr 8 UInt(rrr) UInt(sss)
1076 0 1110ss 0000rr 4 UInt(rr) UInt(ss)
1077 0 11110s 00000r 2 UInt(r) UInt(s)
1078 where all-ones value of S is reserved.
1080 Let's call E the SIMD size.
1082 The immediate value is: S+1 bits '1' rotated to the right by R.
1084 The total of valid encodings is 64*63 + 32*31 + ... + 2*1 = 5334
1085 (remember S != E - 1). */
1087 #define TOTAL_IMM_NB 5334
1092 aarch64_insn encoding;
1093 } simd_imm_encoding;
1095 static simd_imm_encoding simd_immediates[TOTAL_IMM_NB];
1098 simd_imm_encoding_cmp(const void *i1, const void *i2)
1100 const simd_imm_encoding *imm1 = (const simd_imm_encoding *)i1;
1101 const simd_imm_encoding *imm2 = (const simd_imm_encoding *)i2;
1103 if (imm1->imm < imm2->imm)
1105 if (imm1->imm > imm2->imm)
1110 /* immediate bitfield standard encoding
1111 imm13<12> imm13<5:0> imm13<11:6> SIMD size R S
1112 1 ssssss rrrrrr 64 rrrrrr ssssss
1113 0 0sssss 0rrrrr 32 rrrrr sssss
1114 0 10ssss 00rrrr 16 rrrr ssss
1115 0 110sss 000rrr 8 rrr sss
1116 0 1110ss 0000rr 4 rr ss
1117 0 11110s 00000r 2 r s */
1119 encode_immediate_bitfield (int is64, uint32_t s, uint32_t r)
1121 return (is64 << 12) | (r << 6) | s;
1125 build_immediate_table (void)
1127 uint32_t log_e, e, s, r, s_mask;
1133 for (log_e = 1; log_e <= 6; log_e++)
1135 /* Get element size. */
1140 mask = 0xffffffffffffffffull;
1146 mask = (1ull << e) - 1;
1148 1 ((1 << 4) - 1) << 2 = 111100
1149 2 ((1 << 3) - 1) << 3 = 111000
1150 3 ((1 << 2) - 1) << 4 = 110000
1151 4 ((1 << 1) - 1) << 5 = 100000
1152 5 ((1 << 0) - 1) << 6 = 000000 */
1153 s_mask = ((1u << (5 - log_e)) - 1) << (log_e + 1);
1155 for (s = 0; s < e - 1; s++)
1156 for (r = 0; r < e; r++)
1158 /* s+1 consecutive bits to 1 (s < 63) */
1159 imm = (1ull << (s + 1)) - 1;
1160 /* rotate right by r */
1162 imm = (imm >> r) | ((imm << (e - r)) & mask);
1163 /* replicate the constant depending on SIMD size */
1166 case 1: imm = (imm << 2) | imm;
1168 case 2: imm = (imm << 4) | imm;
1170 case 3: imm = (imm << 8) | imm;
1172 case 4: imm = (imm << 16) | imm;
1174 case 5: imm = (imm << 32) | imm;
1179 simd_immediates[nb_imms].imm = imm;
1180 simd_immediates[nb_imms].encoding =
1181 encode_immediate_bitfield(is64, s | s_mask, r);
1185 assert (nb_imms == TOTAL_IMM_NB);
1186 qsort(simd_immediates, nb_imms,
1187 sizeof(simd_immediates[0]), simd_imm_encoding_cmp);
1190 /* Return TRUE if VALUE is a valid logical immediate, i.e. bitmask, that can
1191 be accepted by logical (immediate) instructions
1192 e.g. ORR <Xd|SP>, <Xn>, #<imm>.
1194 ESIZE is the number of bytes in the decoded immediate value.
1195 If ENCODING is not NULL, on the return of TRUE, the standard encoding for
1196 VALUE will be returned in *ENCODING. */
1199 aarch64_logical_immediate_p (uint64_t value, int esize, aarch64_insn *encoding)
1201 simd_imm_encoding imm_enc;
1202 const simd_imm_encoding *imm_encoding;
1203 static bfd_boolean initialized = FALSE;
1207 DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 "), esize: %d", value,
1212 build_immediate_table ();
1216 /* Allow all zeros or all ones in top bits, so that
1217 constant expressions like ~1 are permitted. */
1218 upper = (uint64_t) -1 << (esize * 4) << (esize * 4);
1219 if ((value & ~upper) != value && (value | upper) != value)
1222 /* Replicate to a full 64-bit value. */
1224 for (i = esize * 8; i < 64; i *= 2)
1225 value |= (value << i);
1227 imm_enc.imm = value;
1228 imm_encoding = (const simd_imm_encoding *)
1229 bsearch(&imm_enc, simd_immediates, TOTAL_IMM_NB,
1230 sizeof(simd_immediates[0]), simd_imm_encoding_cmp);
1231 if (imm_encoding == NULL)
1233 DEBUG_TRACE ("exit with FALSE");
1236 if (encoding != NULL)
1237 *encoding = imm_encoding->encoding;
1238 DEBUG_TRACE ("exit with TRUE");
1242 /* If 64-bit immediate IMM is in the format of
1243 "aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh",
1244 where a, b, c, d, e, f, g and h are independently 0 or 1, return an integer
1245 of value "abcdefgh". Otherwise return -1. */
1247 aarch64_shrink_expanded_imm8 (uint64_t imm)
1253 for (i = 0; i < 8; i++)
1255 byte = (imm >> (8 * i)) & 0xff;
1258 else if (byte != 0x00)
1264 /* Utility inline functions for operand_general_constraint_met_p. */
1267 set_error (aarch64_operand_error *mismatch_detail,
1268 enum aarch64_operand_error_kind kind, int idx,
1271 if (mismatch_detail == NULL)
1273 mismatch_detail->kind = kind;
1274 mismatch_detail->index = idx;
1275 mismatch_detail->error = error;
1279 set_syntax_error (aarch64_operand_error *mismatch_detail, int idx,
1282 if (mismatch_detail == NULL)
1284 set_error (mismatch_detail, AARCH64_OPDE_SYNTAX_ERROR, idx, error);
1288 set_out_of_range_error (aarch64_operand_error *mismatch_detail,
1289 int idx, int lower_bound, int upper_bound,
1292 if (mismatch_detail == NULL)
1294 set_error (mismatch_detail, AARCH64_OPDE_OUT_OF_RANGE, idx, error);
1295 mismatch_detail->data[0] = lower_bound;
1296 mismatch_detail->data[1] = upper_bound;
1300 set_imm_out_of_range_error (aarch64_operand_error *mismatch_detail,
1301 int idx, int lower_bound, int upper_bound)
1303 if (mismatch_detail == NULL)
1305 set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1306 _("immediate value"));
1310 set_offset_out_of_range_error (aarch64_operand_error *mismatch_detail,
1311 int idx, int lower_bound, int upper_bound)
1313 if (mismatch_detail == NULL)
1315 set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1316 _("immediate offset"));
1320 set_regno_out_of_range_error (aarch64_operand_error *mismatch_detail,
1321 int idx, int lower_bound, int upper_bound)
1323 if (mismatch_detail == NULL)
1325 set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1326 _("register number"));
1330 set_elem_idx_out_of_range_error (aarch64_operand_error *mismatch_detail,
1331 int idx, int lower_bound, int upper_bound)
1333 if (mismatch_detail == NULL)
1335 set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1336 _("register element index"));
1340 set_sft_amount_out_of_range_error (aarch64_operand_error *mismatch_detail,
1341 int idx, int lower_bound, int upper_bound)
1343 if (mismatch_detail == NULL)
1345 set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1349 /* Report that the MUL modifier in operand IDX should be in the range
1350 [LOWER_BOUND, UPPER_BOUND]. */
1352 set_multiplier_out_of_range_error (aarch64_operand_error *mismatch_detail,
1353 int idx, int lower_bound, int upper_bound)
1355 if (mismatch_detail == NULL)
1357 set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1362 set_unaligned_error (aarch64_operand_error *mismatch_detail, int idx,
1365 if (mismatch_detail == NULL)
1367 set_error (mismatch_detail, AARCH64_OPDE_UNALIGNED, idx, NULL);
1368 mismatch_detail->data[0] = alignment;
1372 set_reg_list_error (aarch64_operand_error *mismatch_detail, int idx,
1375 if (mismatch_detail == NULL)
1377 set_error (mismatch_detail, AARCH64_OPDE_REG_LIST, idx, NULL);
1378 mismatch_detail->data[0] = expected_num;
1382 set_other_error (aarch64_operand_error *mismatch_detail, int idx,
1385 if (mismatch_detail == NULL)
1387 set_error (mismatch_detail, AARCH64_OPDE_OTHER_ERROR, idx, error);
1390 /* General constraint checking based on operand code.
1392 Return 1 if OPNDS[IDX] meets the general constraint of operand code TYPE
1393 as the IDXth operand of opcode OPCODE. Otherwise return 0.
1395 This function has to be called after the qualifiers for all operands
1398 Mismatching error message is returned in *MISMATCH_DETAIL upon request,
1399 i.e. when MISMATCH_DETAIL is non-NULL. This avoids the generation
1400 of error message during the disassembling where error message is not
1401 wanted. We avoid the dynamic construction of strings of error messages
1402 here (i.e. in libopcodes), as it is costly and complicated; instead, we
1403 use a combination of error code, static string and some integer data to
1404 represent an error. */
1407 operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
1408 enum aarch64_opnd type,
1409 const aarch64_opcode *opcode,
1410 aarch64_operand_error *mismatch_detail)
1412 unsigned num, modifiers, shift;
1414 int64_t imm, min_value, max_value;
1415 uint64_t uvalue, mask;
1416 const aarch64_opnd_info *opnd = opnds + idx;
1417 aarch64_opnd_qualifier_t qualifier = opnd->qualifier;
1419 assert (opcode->operands[idx] == opnd->type && opnd->type == type);
1421 switch (aarch64_operands[type].op_class)
1423 case AARCH64_OPND_CLASS_INT_REG:
1424 /* Check pair reg constraints for cas* instructions. */
1425 if (type == AARCH64_OPND_PAIRREG)
1427 assert (idx == 1 || idx == 3);
1428 if (opnds[idx - 1].reg.regno % 2 != 0)
1430 set_syntax_error (mismatch_detail, idx - 1,
1431 _("reg pair must start from even reg"));
1434 if (opnds[idx].reg.regno != opnds[idx - 1].reg.regno + 1)
1436 set_syntax_error (mismatch_detail, idx,
1437 _("reg pair must be contiguous"));
1443 /* <Xt> may be optional in some IC and TLBI instructions. */
1444 if (type == AARCH64_OPND_Rt_SYS)
1446 assert (idx == 1 && (aarch64_get_operand_class (opnds[0].type)
1447 == AARCH64_OPND_CLASS_SYSTEM));
1448 if (opnds[1].present
1449 && !aarch64_sys_ins_reg_has_xt (opnds[0].sysins_op))
1451 set_other_error (mismatch_detail, idx, _("extraneous register"));
1454 if (!opnds[1].present
1455 && aarch64_sys_ins_reg_has_xt (opnds[0].sysins_op))
1457 set_other_error (mismatch_detail, idx, _("missing register"));
1463 case AARCH64_OPND_QLF_WSP:
1464 case AARCH64_OPND_QLF_SP:
1465 if (!aarch64_stack_pointer_p (opnd))
1467 set_other_error (mismatch_detail, idx,
1468 _("stack pointer register expected"));
1477 case AARCH64_OPND_CLASS_SVE_REG:
1480 case AARCH64_OPND_SVE_Zm3_INDEX:
1481 case AARCH64_OPND_SVE_Zm3_22_INDEX:
1482 case AARCH64_OPND_SVE_Zm4_INDEX:
1483 size = get_operand_fields_width (get_operand_from_code (type));
1484 shift = get_operand_specific_data (&aarch64_operands[type]);
1485 mask = (1 << shift) - 1;
1486 if (opnd->reg.regno > mask)
1488 assert (mask == 7 || mask == 15);
1489 set_other_error (mismatch_detail, idx,
1491 ? _("z0-z15 expected")
1492 : _("z0-z7 expected"));
1495 mask = (1 << (size - shift)) - 1;
1496 if (!value_in_range_p (opnd->reglane.index, 0, mask))
1498 set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, mask);
1503 case AARCH64_OPND_SVE_Zn_INDEX:
1504 size = aarch64_get_qualifier_esize (opnd->qualifier);
1505 if (!value_in_range_p (opnd->reglane.index, 0, 64 / size - 1))
1507 set_elem_idx_out_of_range_error (mismatch_detail, idx,
1513 case AARCH64_OPND_SVE_ZnxN:
1514 case AARCH64_OPND_SVE_ZtxN:
1515 if (opnd->reglist.num_regs != get_opcode_dependent_value (opcode))
1517 set_other_error (mismatch_detail, idx,
1518 _("invalid register list"));
1528 case AARCH64_OPND_CLASS_PRED_REG:
1529 if (opnd->reg.regno >= 8
1530 && get_operand_fields_width (get_operand_from_code (type)) == 3)
1532 set_other_error (mismatch_detail, idx, _("p0-p7 expected"));
1537 case AARCH64_OPND_CLASS_COND:
1538 if (type == AARCH64_OPND_COND1
1539 && (opnds[idx].cond->value & 0xe) == 0xe)
1541 /* Not allow AL or NV. */
1542 set_syntax_error (mismatch_detail, idx, NULL);
1546 case AARCH64_OPND_CLASS_ADDRESS:
1547 /* Check writeback. */
1548 switch (opcode->iclass)
1552 case ldstnapair_offs:
1555 if (opnd->addr.writeback == 1)
1557 set_syntax_error (mismatch_detail, idx,
1558 _("unexpected address writeback"));
1563 if (opnd->addr.writeback == 1 && opnd->addr.preind != 1)
1565 set_syntax_error (mismatch_detail, idx,
1566 _("unexpected address writeback"));
1571 case ldstpair_indexed:
1574 if (opnd->addr.writeback == 0)
1576 set_syntax_error (mismatch_detail, idx,
1577 _("address writeback expected"));
1582 assert (opnd->addr.writeback == 0);
1587 case AARCH64_OPND_ADDR_SIMM7:
1588 /* Scaled signed 7 bits immediate offset. */
1589 /* Get the size of the data element that is accessed, which may be
1590 different from that of the source register size,
1591 e.g. in strb/ldrb. */
1592 size = aarch64_get_qualifier_esize (opnd->qualifier);
1593 if (!value_in_range_p (opnd->addr.offset.imm, -64 * size, 63 * size))
1595 set_offset_out_of_range_error (mismatch_detail, idx,
1596 -64 * size, 63 * size);
1599 if (!value_aligned_p (opnd->addr.offset.imm, size))
1601 set_unaligned_error (mismatch_detail, idx, size);
1605 case AARCH64_OPND_ADDR_SIMM9:
1606 /* Unscaled signed 9 bits immediate offset. */
1607 if (!value_in_range_p (opnd->addr.offset.imm, -256, 255))
1609 set_offset_out_of_range_error (mismatch_detail, idx, -256, 255);
1614 case AARCH64_OPND_ADDR_SIMM9_2:
1615 /* Unscaled signed 9 bits immediate offset, which has to be negative
1617 size = aarch64_get_qualifier_esize (qualifier);
1618 if ((value_in_range_p (opnd->addr.offset.imm, 0, 255)
1619 && !value_aligned_p (opnd->addr.offset.imm, size))
1620 || value_in_range_p (opnd->addr.offset.imm, -256, -1))
1622 set_other_error (mismatch_detail, idx,
1623 _("negative or unaligned offset expected"));
1626 case AARCH64_OPND_ADDR_SIMM10:
1627 /* Scaled signed 10 bits immediate offset. */
1628 if (!value_in_range_p (opnd->addr.offset.imm, -4096, 4088))
1630 set_offset_out_of_range_error (mismatch_detail, idx, -4096, 4088);
1633 if (!value_aligned_p (opnd->addr.offset.imm, 8))
1635 set_unaligned_error (mismatch_detail, idx, 8);
1640 case AARCH64_OPND_SIMD_ADDR_POST:
1641 /* AdvSIMD load/store multiple structures, post-index. */
1643 if (opnd->addr.offset.is_reg)
1645 if (value_in_range_p (opnd->addr.offset.regno, 0, 30))
1649 set_other_error (mismatch_detail, idx,
1650 _("invalid register offset"));
1656 const aarch64_opnd_info *prev = &opnds[idx-1];
1657 unsigned num_bytes; /* total number of bytes transferred. */
1658 /* The opcode dependent area stores the number of elements in
1659 each structure to be loaded/stored. */
1660 int is_ld1r = get_opcode_dependent_value (opcode) == 1;
1661 if (opcode->operands[0] == AARCH64_OPND_LVt_AL)
1662 /* Special handling of loading single structure to all lane. */
1663 num_bytes = (is_ld1r ? 1 : prev->reglist.num_regs)
1664 * aarch64_get_qualifier_esize (prev->qualifier);
1666 num_bytes = prev->reglist.num_regs
1667 * aarch64_get_qualifier_esize (prev->qualifier)
1668 * aarch64_get_qualifier_nelem (prev->qualifier);
1669 if ((int) num_bytes != opnd->addr.offset.imm)
1671 set_other_error (mismatch_detail, idx,
1672 _("invalid post-increment amount"));
1678 case AARCH64_OPND_ADDR_REGOFF:
1679 /* Get the size of the data element that is accessed, which may be
1680 different from that of the source register size,
1681 e.g. in strb/ldrb. */
1682 size = aarch64_get_qualifier_esize (opnd->qualifier);
1683 /* It is either no shift or shift by the binary logarithm of SIZE. */
1684 if (opnd->shifter.amount != 0
1685 && opnd->shifter.amount != (int)get_logsz (size))
1687 set_other_error (mismatch_detail, idx,
1688 _("invalid shift amount"));
1691 /* Only UXTW, LSL, SXTW and SXTX are the accepted extending
1693 switch (opnd->shifter.kind)
1695 case AARCH64_MOD_UXTW:
1696 case AARCH64_MOD_LSL:
1697 case AARCH64_MOD_SXTW:
1698 case AARCH64_MOD_SXTX: break;
1700 set_other_error (mismatch_detail, idx,
1701 _("invalid extend/shift operator"));
1706 case AARCH64_OPND_ADDR_UIMM12:
1707 imm = opnd->addr.offset.imm;
1708 /* Get the size of the data element that is accessed, which may be
1709 different from that of the source register size,
1710 e.g. in strb/ldrb. */
1711 size = aarch64_get_qualifier_esize (qualifier);
1712 if (!value_in_range_p (opnd->addr.offset.imm, 0, 4095 * size))
1714 set_offset_out_of_range_error (mismatch_detail, idx,
1718 if (!value_aligned_p (opnd->addr.offset.imm, size))
1720 set_unaligned_error (mismatch_detail, idx, size);
1725 case AARCH64_OPND_ADDR_PCREL14:
1726 case AARCH64_OPND_ADDR_PCREL19:
1727 case AARCH64_OPND_ADDR_PCREL21:
1728 case AARCH64_OPND_ADDR_PCREL26:
1729 imm = opnd->imm.value;
1730 if (operand_need_shift_by_two (get_operand_from_code (type)))
1732 /* The offset value in a PC-relative branch instruction is alway
1733 4-byte aligned and is encoded without the lowest 2 bits. */
1734 if (!value_aligned_p (imm, 4))
1736 set_unaligned_error (mismatch_detail, idx, 4);
1739 /* Right shift by 2 so that we can carry out the following check
1743 size = get_operand_fields_width (get_operand_from_code (type));
1744 if (!value_fit_signed_field_p (imm, size))
1746 set_other_error (mismatch_detail, idx,
1747 _("immediate out of range"));
1752 case AARCH64_OPND_SVE_ADDR_RI_S4xVL:
1753 case AARCH64_OPND_SVE_ADDR_RI_S4x2xVL:
1754 case AARCH64_OPND_SVE_ADDR_RI_S4x3xVL:
1755 case AARCH64_OPND_SVE_ADDR_RI_S4x4xVL:
1759 assert (!opnd->addr.offset.is_reg);
1760 assert (opnd->addr.preind);
1761 num = 1 + get_operand_specific_data (&aarch64_operands[type]);
1764 if ((opnd->addr.offset.imm != 0 && !opnd->shifter.operator_present)
1765 || (opnd->shifter.operator_present
1766 && opnd->shifter.kind != AARCH64_MOD_MUL_VL))
1768 set_other_error (mismatch_detail, idx,
1769 _("invalid addressing mode"));
1772 if (!value_in_range_p (opnd->addr.offset.imm, min_value, max_value))
1774 set_offset_out_of_range_error (mismatch_detail, idx,
1775 min_value, max_value);
1778 if (!value_aligned_p (opnd->addr.offset.imm, num))
1780 set_unaligned_error (mismatch_detail, idx, num);
1785 case AARCH64_OPND_SVE_ADDR_RI_S6xVL:
1788 goto sve_imm_offset_vl;
1790 case AARCH64_OPND_SVE_ADDR_RI_S9xVL:
1793 goto sve_imm_offset_vl;
1795 case AARCH64_OPND_SVE_ADDR_RI_U6:
1796 case AARCH64_OPND_SVE_ADDR_RI_U6x2:
1797 case AARCH64_OPND_SVE_ADDR_RI_U6x4:
1798 case AARCH64_OPND_SVE_ADDR_RI_U6x8:
1802 assert (!opnd->addr.offset.is_reg);
1803 assert (opnd->addr.preind);
1804 num = 1 << get_operand_specific_data (&aarch64_operands[type]);
1807 if (opnd->shifter.operator_present
1808 || opnd->shifter.amount_present)
1810 set_other_error (mismatch_detail, idx,
1811 _("invalid addressing mode"));
1814 if (!value_in_range_p (opnd->addr.offset.imm, min_value, max_value))
1816 set_offset_out_of_range_error (mismatch_detail, idx,
1817 min_value, max_value);
1820 if (!value_aligned_p (opnd->addr.offset.imm, num))
1822 set_unaligned_error (mismatch_detail, idx, num);
1827 case AARCH64_OPND_SVE_ADDR_RI_S4x16:
1830 goto sve_imm_offset;
1832 case AARCH64_OPND_SVE_ADDR_RR:
1833 case AARCH64_OPND_SVE_ADDR_RR_LSL1:
1834 case AARCH64_OPND_SVE_ADDR_RR_LSL2:
1835 case AARCH64_OPND_SVE_ADDR_RR_LSL3:
1836 case AARCH64_OPND_SVE_ADDR_RX:
1837 case AARCH64_OPND_SVE_ADDR_RX_LSL1:
1838 case AARCH64_OPND_SVE_ADDR_RX_LSL2:
1839 case AARCH64_OPND_SVE_ADDR_RX_LSL3:
1840 case AARCH64_OPND_SVE_ADDR_RZ:
1841 case AARCH64_OPND_SVE_ADDR_RZ_LSL1:
1842 case AARCH64_OPND_SVE_ADDR_RZ_LSL2:
1843 case AARCH64_OPND_SVE_ADDR_RZ_LSL3:
1844 modifiers = 1 << AARCH64_MOD_LSL;
1846 assert (opnd->addr.offset.is_reg);
1847 assert (opnd->addr.preind);
1848 if ((aarch64_operands[type].flags & OPD_F_NO_ZR) != 0
1849 && opnd->addr.offset.regno == 31)
1851 set_other_error (mismatch_detail, idx,
1852 _("index register xzr is not allowed"));
1855 if (((1 << opnd->shifter.kind) & modifiers) == 0
1856 || (opnd->shifter.amount
1857 != get_operand_specific_data (&aarch64_operands[type])))
1859 set_other_error (mismatch_detail, idx,
1860 _("invalid addressing mode"));
1865 case AARCH64_OPND_SVE_ADDR_RZ_XTW_14:
1866 case AARCH64_OPND_SVE_ADDR_RZ_XTW_22:
1867 case AARCH64_OPND_SVE_ADDR_RZ_XTW1_14:
1868 case AARCH64_OPND_SVE_ADDR_RZ_XTW1_22:
1869 case AARCH64_OPND_SVE_ADDR_RZ_XTW2_14:
1870 case AARCH64_OPND_SVE_ADDR_RZ_XTW2_22:
1871 case AARCH64_OPND_SVE_ADDR_RZ_XTW3_14:
1872 case AARCH64_OPND_SVE_ADDR_RZ_XTW3_22:
1873 modifiers = (1 << AARCH64_MOD_SXTW) | (1 << AARCH64_MOD_UXTW);
1874 goto sve_rr_operand;
1876 case AARCH64_OPND_SVE_ADDR_ZI_U5:
1877 case AARCH64_OPND_SVE_ADDR_ZI_U5x2:
1878 case AARCH64_OPND_SVE_ADDR_ZI_U5x4:
1879 case AARCH64_OPND_SVE_ADDR_ZI_U5x8:
1882 goto sve_imm_offset;
1884 case AARCH64_OPND_SVE_ADDR_ZZ_LSL:
1885 modifiers = 1 << AARCH64_MOD_LSL;
1887 assert (opnd->addr.offset.is_reg);
1888 assert (opnd->addr.preind);
1889 if (((1 << opnd->shifter.kind) & modifiers) == 0
1890 || opnd->shifter.amount < 0
1891 || opnd->shifter.amount > 3)
1893 set_other_error (mismatch_detail, idx,
1894 _("invalid addressing mode"));
1899 case AARCH64_OPND_SVE_ADDR_ZZ_SXTW:
1900 modifiers = (1 << AARCH64_MOD_SXTW);
1901 goto sve_zz_operand;
1903 case AARCH64_OPND_SVE_ADDR_ZZ_UXTW:
1904 modifiers = 1 << AARCH64_MOD_UXTW;
1905 goto sve_zz_operand;
1912 case AARCH64_OPND_CLASS_SIMD_REGLIST:
1913 if (type == AARCH64_OPND_LEt)
1915 /* Get the upper bound for the element index. */
1916 num = 16 / aarch64_get_qualifier_esize (qualifier) - 1;
1917 if (!value_in_range_p (opnd->reglist.index, 0, num))
1919 set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, num);
1923 /* The opcode dependent area stores the number of elements in
1924 each structure to be loaded/stored. */
1925 num = get_opcode_dependent_value (opcode);
1928 case AARCH64_OPND_LVt:
1929 assert (num >= 1 && num <= 4);
1930 /* Unless LD1/ST1, the number of registers should be equal to that
1931 of the structure elements. */
1932 if (num != 1 && opnd->reglist.num_regs != num)
1934 set_reg_list_error (mismatch_detail, idx, num);
1938 case AARCH64_OPND_LVt_AL:
1939 case AARCH64_OPND_LEt:
1940 assert (num >= 1 && num <= 4);
1941 /* The number of registers should be equal to that of the structure
1943 if (opnd->reglist.num_regs != num)
1945 set_reg_list_error (mismatch_detail, idx, num);
1954 case AARCH64_OPND_CLASS_IMMEDIATE:
1955 /* Constraint check on immediate operand. */
1956 imm = opnd->imm.value;
1957 /* E.g. imm_0_31 constrains value to be 0..31. */
1958 if (qualifier_value_in_range_constraint_p (qualifier)
1959 && !value_in_range_p (imm, get_lower_bound (qualifier),
1960 get_upper_bound (qualifier)))
1962 set_imm_out_of_range_error (mismatch_detail, idx,
1963 get_lower_bound (qualifier),
1964 get_upper_bound (qualifier));
1970 case AARCH64_OPND_AIMM:
1971 if (opnd->shifter.kind != AARCH64_MOD_LSL)
1973 set_other_error (mismatch_detail, idx,
1974 _("invalid shift operator"));
1977 if (opnd->shifter.amount != 0 && opnd->shifter.amount != 12)
1979 set_other_error (mismatch_detail, idx,
1980 _("shift amount must be 0 or 12"));
1983 if (!value_fit_unsigned_field_p (opnd->imm.value, 12))
1985 set_other_error (mismatch_detail, idx,
1986 _("immediate out of range"));
1991 case AARCH64_OPND_HALF:
1992 assert (idx == 1 && opnds[0].type == AARCH64_OPND_Rd);
1993 if (opnd->shifter.kind != AARCH64_MOD_LSL)
1995 set_other_error (mismatch_detail, idx,
1996 _("invalid shift operator"));
1999 size = aarch64_get_qualifier_esize (opnds[0].qualifier);
2000 if (!value_aligned_p (opnd->shifter.amount, 16))
2002 set_other_error (mismatch_detail, idx,
2003 _("shift amount must be a multiple of 16"));
2006 if (!value_in_range_p (opnd->shifter.amount, 0, size * 8 - 16))
2008 set_sft_amount_out_of_range_error (mismatch_detail, idx,
2012 if (opnd->imm.value < 0)
2014 set_other_error (mismatch_detail, idx,
2015 _("negative immediate value not allowed"));
2018 if (!value_fit_unsigned_field_p (opnd->imm.value, 16))
2020 set_other_error (mismatch_detail, idx,
2021 _("immediate out of range"));
2026 case AARCH64_OPND_IMM_MOV:
2028 int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
2029 imm = opnd->imm.value;
2033 case OP_MOV_IMM_WIDEN:
2036 case OP_MOV_IMM_WIDE:
2037 if (!aarch64_wide_constant_p (imm, esize == 4, NULL))
2039 set_other_error (mismatch_detail, idx,
2040 _("immediate out of range"));
2044 case OP_MOV_IMM_LOG:
2045 if (!aarch64_logical_immediate_p (imm, esize, NULL))
2047 set_other_error (mismatch_detail, idx,
2048 _("immediate out of range"));
2059 case AARCH64_OPND_NZCV:
2060 case AARCH64_OPND_CCMP_IMM:
2061 case AARCH64_OPND_EXCEPTION:
2062 case AARCH64_OPND_UIMM4:
2063 case AARCH64_OPND_UIMM7:
2064 case AARCH64_OPND_UIMM3_OP1:
2065 case AARCH64_OPND_UIMM3_OP2:
2066 case AARCH64_OPND_SVE_UIMM3:
2067 case AARCH64_OPND_SVE_UIMM7:
2068 case AARCH64_OPND_SVE_UIMM8:
2069 case AARCH64_OPND_SVE_UIMM8_53:
2070 size = get_operand_fields_width (get_operand_from_code (type));
2072 if (!value_fit_unsigned_field_p (opnd->imm.value, size))
2074 set_imm_out_of_range_error (mismatch_detail, idx, 0,
2080 case AARCH64_OPND_SIMM5:
2081 case AARCH64_OPND_SVE_SIMM5:
2082 case AARCH64_OPND_SVE_SIMM5B:
2083 case AARCH64_OPND_SVE_SIMM6:
2084 case AARCH64_OPND_SVE_SIMM8:
2085 size = get_operand_fields_width (get_operand_from_code (type));
2087 if (!value_fit_signed_field_p (opnd->imm.value, size))
2089 set_imm_out_of_range_error (mismatch_detail, idx,
2091 (1 << (size - 1)) - 1);
2096 case AARCH64_OPND_WIDTH:
2097 assert (idx > 1 && opnds[idx-1].type == AARCH64_OPND_IMM
2098 && opnds[0].type == AARCH64_OPND_Rd);
2099 size = get_upper_bound (qualifier);
2100 if (opnd->imm.value + opnds[idx-1].imm.value > size)
2101 /* lsb+width <= reg.size */
2103 set_imm_out_of_range_error (mismatch_detail, idx, 1,
2104 size - opnds[idx-1].imm.value);
2109 case AARCH64_OPND_LIMM:
2110 case AARCH64_OPND_SVE_LIMM:
2112 int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
2113 uint64_t uimm = opnd->imm.value;
2114 if (opcode->op == OP_BIC)
2116 if (!aarch64_logical_immediate_p (uimm, esize, NULL))
2118 set_other_error (mismatch_detail, idx,
2119 _("immediate out of range"));
2125 case AARCH64_OPND_IMM0:
2126 case AARCH64_OPND_FPIMM0:
2127 if (opnd->imm.value != 0)
2129 set_other_error (mismatch_detail, idx,
2130 _("immediate zero expected"));
2135 case AARCH64_OPND_IMM_ROT1:
2136 case AARCH64_OPND_IMM_ROT2:
2137 case AARCH64_OPND_SVE_IMM_ROT2:
2138 if (opnd->imm.value != 0
2139 && opnd->imm.value != 90
2140 && opnd->imm.value != 180
2141 && opnd->imm.value != 270)
2143 set_other_error (mismatch_detail, idx,
2144 _("rotate expected to be 0, 90, 180 or 270"));
2149 case AARCH64_OPND_IMM_ROT3:
2150 case AARCH64_OPND_SVE_IMM_ROT1:
2151 if (opnd->imm.value != 90 && opnd->imm.value != 270)
2153 set_other_error (mismatch_detail, idx,
2154 _("rotate expected to be 90 or 270"));
2159 case AARCH64_OPND_SHLL_IMM:
2161 size = 8 * aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
2162 if (opnd->imm.value != size)
2164 set_other_error (mismatch_detail, idx,
2165 _("invalid shift amount"));
2170 case AARCH64_OPND_IMM_VLSL:
2171 size = aarch64_get_qualifier_esize (qualifier);
2172 if (!value_in_range_p (opnd->imm.value, 0, size * 8 - 1))
2174 set_imm_out_of_range_error (mismatch_detail, idx, 0,
2180 case AARCH64_OPND_IMM_VLSR:
2181 size = aarch64_get_qualifier_esize (qualifier);
2182 if (!value_in_range_p (opnd->imm.value, 1, size * 8))
2184 set_imm_out_of_range_error (mismatch_detail, idx, 1, size * 8);
2189 case AARCH64_OPND_SIMD_IMM:
2190 case AARCH64_OPND_SIMD_IMM_SFT:
2191 /* Qualifier check. */
2194 case AARCH64_OPND_QLF_LSL:
2195 if (opnd->shifter.kind != AARCH64_MOD_LSL)
2197 set_other_error (mismatch_detail, idx,
2198 _("invalid shift operator"));
2202 case AARCH64_OPND_QLF_MSL:
2203 if (opnd->shifter.kind != AARCH64_MOD_MSL)
2205 set_other_error (mismatch_detail, idx,
2206 _("invalid shift operator"));
2210 case AARCH64_OPND_QLF_NIL:
2211 if (opnd->shifter.kind != AARCH64_MOD_NONE)
2213 set_other_error (mismatch_detail, idx,
2214 _("shift is not permitted"));
2222 /* Is the immediate valid? */
2224 if (aarch64_get_qualifier_esize (opnds[0].qualifier) != 8)
2226 /* uimm8 or simm8 */
2227 if (!value_in_range_p (opnd->imm.value, -128, 255))
2229 set_imm_out_of_range_error (mismatch_detail, idx, -128, 255);
2233 else if (aarch64_shrink_expanded_imm8 (opnd->imm.value) < 0)
2236 'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeee
2237 ffffffffgggggggghhhhhhhh'. */
2238 set_other_error (mismatch_detail, idx,
2239 _("invalid value for immediate"));
2242 /* Is the shift amount valid? */
2243 switch (opnd->shifter.kind)
2245 case AARCH64_MOD_LSL:
2246 size = aarch64_get_qualifier_esize (opnds[0].qualifier);
2247 if (!value_in_range_p (opnd->shifter.amount, 0, (size - 1) * 8))
2249 set_sft_amount_out_of_range_error (mismatch_detail, idx, 0,
2253 if (!value_aligned_p (opnd->shifter.amount, 8))
2255 set_unaligned_error (mismatch_detail, idx, 8);
2259 case AARCH64_MOD_MSL:
2260 /* Only 8 and 16 are valid shift amount. */
2261 if (opnd->shifter.amount != 8 && opnd->shifter.amount != 16)
2263 set_other_error (mismatch_detail, idx,
2264 _("shift amount must be 0 or 16"));
2269 if (opnd->shifter.kind != AARCH64_MOD_NONE)
2271 set_other_error (mismatch_detail, idx,
2272 _("invalid shift operator"));
2279 case AARCH64_OPND_FPIMM:
2280 case AARCH64_OPND_SIMD_FPIMM:
2281 case AARCH64_OPND_SVE_FPIMM8:
2282 if (opnd->imm.is_fp == 0)
2284 set_other_error (mismatch_detail, idx,
2285 _("floating-point immediate expected"));
2288 /* The value is expected to be an 8-bit floating-point constant with
2289 sign, 3-bit exponent and normalized 4 bits of precision, encoded
2290 in "a:b:c:d:e:f:g:h" or FLD_imm8 (depending on the type of the
2292 if (!value_in_range_p (opnd->imm.value, 0, 255))
2294 set_other_error (mismatch_detail, idx,
2295 _("immediate out of range"));
2298 if (opnd->shifter.kind != AARCH64_MOD_NONE)
2300 set_other_error (mismatch_detail, idx,
2301 _("invalid shift operator"));
2306 case AARCH64_OPND_SVE_AIMM:
2309 assert (opnd->shifter.kind == AARCH64_MOD_LSL);
2310 size = aarch64_get_qualifier_esize (opnds[0].qualifier);
2311 mask = ~((uint64_t) -1 << (size * 4) << (size * 4));
2312 uvalue = opnd->imm.value;
2313 shift = opnd->shifter.amount;
2318 set_other_error (mismatch_detail, idx,
2319 _("no shift amount allowed for"
2320 " 8-bit constants"));
2326 if (shift != 0 && shift != 8)
2328 set_other_error (mismatch_detail, idx,
2329 _("shift amount must be 0 or 8"));
2332 if (shift == 0 && (uvalue & 0xff) == 0)
2335 uvalue = (int64_t) uvalue / 256;
2339 if ((uvalue & mask) != uvalue && (uvalue | ~mask) != uvalue)
2341 set_other_error (mismatch_detail, idx,
2342 _("immediate too big for element size"));
2345 uvalue = (uvalue - min_value) & mask;
2348 set_other_error (mismatch_detail, idx,
2349 _("invalid arithmetic immediate"));
2354 case AARCH64_OPND_SVE_ASIMM:
2358 case AARCH64_OPND_SVE_I1_HALF_ONE:
2359 assert (opnd->imm.is_fp);
2360 if (opnd->imm.value != 0x3f000000 && opnd->imm.value != 0x3f800000)
2362 set_other_error (mismatch_detail, idx,
2363 _("floating-point value must be 0.5 or 1.0"));
2368 case AARCH64_OPND_SVE_I1_HALF_TWO:
2369 assert (opnd->imm.is_fp);
2370 if (opnd->imm.value != 0x3f000000 && opnd->imm.value != 0x40000000)
2372 set_other_error (mismatch_detail, idx,
2373 _("floating-point value must be 0.5 or 2.0"));
2378 case AARCH64_OPND_SVE_I1_ZERO_ONE:
2379 assert (opnd->imm.is_fp);
2380 if (opnd->imm.value != 0 && opnd->imm.value != 0x3f800000)
2382 set_other_error (mismatch_detail, idx,
2383 _("floating-point value must be 0.0 or 1.0"));
2388 case AARCH64_OPND_SVE_INV_LIMM:
2390 int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
2391 uint64_t uimm = ~opnd->imm.value;
2392 if (!aarch64_logical_immediate_p (uimm, esize, NULL))
2394 set_other_error (mismatch_detail, idx,
2395 _("immediate out of range"));
2401 case AARCH64_OPND_SVE_LIMM_MOV:
2403 int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
2404 uint64_t uimm = opnd->imm.value;
2405 if (!aarch64_logical_immediate_p (uimm, esize, NULL))
2407 set_other_error (mismatch_detail, idx,
2408 _("immediate out of range"));
2411 if (!aarch64_sve_dupm_mov_immediate_p (uimm, esize))
2413 set_other_error (mismatch_detail, idx,
2414 _("invalid replicated MOV immediate"));
2420 case AARCH64_OPND_SVE_PATTERN_SCALED:
2421 assert (opnd->shifter.kind == AARCH64_MOD_MUL);
2422 if (!value_in_range_p (opnd->shifter.amount, 1, 16))
2424 set_multiplier_out_of_range_error (mismatch_detail, idx, 1, 16);
2429 case AARCH64_OPND_SVE_SHLIMM_PRED:
2430 case AARCH64_OPND_SVE_SHLIMM_UNPRED:
2431 size = aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
2432 if (!value_in_range_p (opnd->imm.value, 0, 8 * size - 1))
2434 set_imm_out_of_range_error (mismatch_detail, idx,
2440 case AARCH64_OPND_SVE_SHRIMM_PRED:
2441 case AARCH64_OPND_SVE_SHRIMM_UNPRED:
2442 size = aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
2443 if (!value_in_range_p (opnd->imm.value, 1, 8 * size))
2445 set_imm_out_of_range_error (mismatch_detail, idx, 1, 8 * size);
2455 case AARCH64_OPND_CLASS_SYSTEM:
2458 case AARCH64_OPND_PSTATEFIELD:
2459 assert (idx == 0 && opnds[1].type == AARCH64_OPND_UIMM4);
2462 The immediate must be #0 or #1. */
2463 if ((opnd->pstatefield == 0x03 /* UAO. */
2464 || opnd->pstatefield == 0x04) /* PAN. */
2465 && opnds[1].imm.value > 1)
2467 set_imm_out_of_range_error (mismatch_detail, idx, 0, 1);
2470 /* MSR SPSel, #uimm4
2471 Uses uimm4 as a control value to select the stack pointer: if
2472 bit 0 is set it selects the current exception level's stack
2473 pointer, if bit 0 is clear it selects shared EL0 stack pointer.
2474 Bits 1 to 3 of uimm4 are reserved and should be zero. */
2475 if (opnd->pstatefield == 0x05 /* spsel */ && opnds[1].imm.value > 1)
2477 set_imm_out_of_range_error (mismatch_detail, idx, 0, 1);
2486 case AARCH64_OPND_CLASS_SIMD_ELEMENT:
2487 /* Get the upper bound for the element index. */
2488 if (opcode->op == OP_FCMLA_ELEM)
2489 /* FCMLA index range depends on the vector size of other operands
2490 and is halfed because complex numbers take two elements. */
2491 num = aarch64_get_qualifier_nelem (opnds[0].qualifier)
2492 * aarch64_get_qualifier_esize (opnds[0].qualifier) / 2;
2495 num = num / aarch64_get_qualifier_esize (qualifier) - 1;
2497 /* Index out-of-range. */
2498 if (!value_in_range_p (opnd->reglane.index, 0, num))
2500 set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, num);
2503 /* SMLAL<Q> <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>].
2504 <Vm> Is the vector register (V0-V31) or (V0-V15), whose
2505 number is encoded in "size:M:Rm":
2511 if (type == AARCH64_OPND_Em && qualifier == AARCH64_OPND_QLF_S_H
2512 && !value_in_range_p (opnd->reglane.regno, 0, 15))
2514 set_regno_out_of_range_error (mismatch_detail, idx, 0, 15);
2519 case AARCH64_OPND_CLASS_MODIFIED_REG:
2520 assert (idx == 1 || idx == 2);
2523 case AARCH64_OPND_Rm_EXT:
2524 if (!aarch64_extend_operator_p (opnd->shifter.kind)
2525 && opnd->shifter.kind != AARCH64_MOD_LSL)
2527 set_other_error (mismatch_detail, idx,
2528 _("extend operator expected"));
2531 /* It is not optional unless at least one of "Rd" or "Rn" is '11111'
2532 (i.e. SP), in which case it defaults to LSL. The LSL alias is
2533 only valid when "Rd" or "Rn" is '11111', and is preferred in that
2535 if (!aarch64_stack_pointer_p (opnds + 0)
2536 && (idx != 2 || !aarch64_stack_pointer_p (opnds + 1)))
2538 if (!opnd->shifter.operator_present)
2540 set_other_error (mismatch_detail, idx,
2541 _("missing extend operator"));
2544 else if (opnd->shifter.kind == AARCH64_MOD_LSL)
2546 set_other_error (mismatch_detail, idx,
2547 _("'LSL' operator not allowed"));
2551 assert (opnd->shifter.operator_present /* Default to LSL. */
2552 || opnd->shifter.kind == AARCH64_MOD_LSL);
2553 if (!value_in_range_p (opnd->shifter.amount, 0, 4))
2555 set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, 4);
2558 /* In the 64-bit form, the final register operand is written as Wm
2559 for all but the (possibly omitted) UXTX/LSL and SXTX
2561 N.B. GAS allows X register to be used with any operator as a
2562 programming convenience. */
2563 if (qualifier == AARCH64_OPND_QLF_X
2564 && opnd->shifter.kind != AARCH64_MOD_LSL
2565 && opnd->shifter.kind != AARCH64_MOD_UXTX
2566 && opnd->shifter.kind != AARCH64_MOD_SXTX)
2568 set_other_error (mismatch_detail, idx, _("W register expected"));
2573 case AARCH64_OPND_Rm_SFT:
2574 /* ROR is not available to the shifted register operand in
2575 arithmetic instructions. */
2576 if (!aarch64_shift_operator_p (opnd->shifter.kind))
2578 set_other_error (mismatch_detail, idx,
2579 _("shift operator expected"));
2582 if (opnd->shifter.kind == AARCH64_MOD_ROR
2583 && opcode->iclass != log_shift)
2585 set_other_error (mismatch_detail, idx,
2586 _("'ROR' operator not allowed"));
2589 num = qualifier == AARCH64_OPND_QLF_W ? 31 : 63;
2590 if (!value_in_range_p (opnd->shifter.amount, 0, num))
2592 set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, num);
2609 /* Main entrypoint for the operand constraint checking.
2611 Return 1 if operands of *INST meet the constraint applied by the operand
2612 codes and operand qualifiers; otherwise return 0 and if MISMATCH_DETAIL is
2613 not NULL, return the detail of the error in *MISMATCH_DETAIL. N.B. when
2614 adding more constraint checking, make sure MISMATCH_DETAIL->KIND is set
2615 with a proper error kind rather than AARCH64_OPDE_NIL (GAS asserts non-NIL
2616 error kind when it is notified that an instruction does not pass the check).
2618 Un-determined operand qualifiers may get established during the process. */
2621 aarch64_match_operands_constraint (aarch64_inst *inst,
2622 aarch64_operand_error *mismatch_detail)
2626 DEBUG_TRACE ("enter");
2628 /* Check for cases where a source register needs to be the same as the
2629 destination register. Do this before matching qualifiers since if
2630 an instruction has both invalid tying and invalid qualifiers,
2631 the error about qualifiers would suggest several alternative
2632 instructions that also have invalid tying. */
2633 i = inst->opcode->tied_operand;
2634 if (i > 0 && (inst->operands[0].reg.regno != inst->operands[i].reg.regno))
2636 if (mismatch_detail)
2638 mismatch_detail->kind = AARCH64_OPDE_UNTIED_OPERAND;
2639 mismatch_detail->index = i;
2640 mismatch_detail->error = NULL;
2645 /* Match operands' qualifier.
2646 *INST has already had qualifier establish for some, if not all, of
2647 its operands; we need to find out whether these established
2648 qualifiers match one of the qualifier sequence in
2649 INST->OPCODE->QUALIFIERS_LIST. If yes, we will assign each operand
2650 with the corresponding qualifier in such a sequence.
2651 Only basic operand constraint checking is done here; the more thorough
2652 constraint checking will carried out by operand_general_constraint_met_p,
2653 which has be to called after this in order to get all of the operands'
2654 qualifiers established. */
2655 if (match_operands_qualifier (inst, TRUE /* update_p */) == 0)
2657 DEBUG_TRACE ("FAIL on operand qualifier matching");
2658 if (mismatch_detail)
2660 /* Return an error type to indicate that it is the qualifier
2661 matching failure; we don't care about which operand as there
2662 are enough information in the opcode table to reproduce it. */
2663 mismatch_detail->kind = AARCH64_OPDE_INVALID_VARIANT;
2664 mismatch_detail->index = -1;
2665 mismatch_detail->error = NULL;
2670 /* Match operands' constraint. */
2671 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2673 enum aarch64_opnd type = inst->opcode->operands[i];
2674 if (type == AARCH64_OPND_NIL)
2676 if (inst->operands[i].skip)
2678 DEBUG_TRACE ("skip the incomplete operand %d", i);
2681 if (operand_general_constraint_met_p (inst->operands, i, type,
2682 inst->opcode, mismatch_detail) == 0)
2684 DEBUG_TRACE ("FAIL on operand %d", i);
2689 DEBUG_TRACE ("PASS");
2694 /* Replace INST->OPCODE with OPCODE and return the replaced OPCODE.
2695 Also updates the TYPE of each INST->OPERANDS with the corresponding
2696 value of OPCODE->OPERANDS.
2698 Note that some operand qualifiers may need to be manually cleared by
2699 the caller before it further calls the aarch64_opcode_encode; by
2700 doing this, it helps the qualifier matching facilities work
2703 const aarch64_opcode*
2704 aarch64_replace_opcode (aarch64_inst *inst, const aarch64_opcode *opcode)
2707 const aarch64_opcode *old = inst->opcode;
2709 inst->opcode = opcode;
2711 /* Update the operand types. */
2712 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2714 inst->operands[i].type = opcode->operands[i];
2715 if (opcode->operands[i] == AARCH64_OPND_NIL)
2719 DEBUG_TRACE ("replace %s with %s", old->name, opcode->name);
2725 aarch64_operand_index (const enum aarch64_opnd *operands, enum aarch64_opnd operand)
2728 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2729 if (operands[i] == operand)
2731 else if (operands[i] == AARCH64_OPND_NIL)
2736 /* R0...R30, followed by FOR31. */
2737 #define BANK(R, FOR31) \
2738 { R (0), R (1), R (2), R (3), R (4), R (5), R (6), R (7), \
2739 R (8), R (9), R (10), R (11), R (12), R (13), R (14), R (15), \
2740 R (16), R (17), R (18), R (19), R (20), R (21), R (22), R (23), \
2741 R (24), R (25), R (26), R (27), R (28), R (29), R (30), FOR31 }
2742 /* [0][0] 32-bit integer regs with sp Wn
2743 [0][1] 64-bit integer regs with sp Xn sf=1
2744 [1][0] 32-bit integer regs with #0 Wn
2745 [1][1] 64-bit integer regs with #0 Xn sf=1 */
2746 static const char *int_reg[2][2][32] = {
2747 #define R32(X) "w" #X
2748 #define R64(X) "x" #X
2749 { BANK (R32, "wsp"), BANK (R64, "sp") },
2750 { BANK (R32, "wzr"), BANK (R64, "xzr") }
2755 /* Names of the SVE vector registers, first with .S suffixes,
2756 then with .D suffixes. */
2758 static const char *sve_reg[2][32] = {
2759 #define ZS(X) "z" #X ".s"
2760 #define ZD(X) "z" #X ".d"
2761 BANK (ZS, ZS (31)), BANK (ZD, ZD (31))
2767 /* Return the integer register name.
2768 if SP_REG_P is not 0, R31 is an SP reg, other R31 is the zero reg. */
2770 static inline const char *
2771 get_int_reg_name (int regno, aarch64_opnd_qualifier_t qualifier, int sp_reg_p)
2773 const int has_zr = sp_reg_p ? 0 : 1;
2774 const int is_64 = aarch64_get_qualifier_esize (qualifier) == 4 ? 0 : 1;
2775 return int_reg[has_zr][is_64][regno];
2778 /* Like get_int_reg_name, but IS_64 is always 1. */
2780 static inline const char *
2781 get_64bit_int_reg_name (int regno, int sp_reg_p)
2783 const int has_zr = sp_reg_p ? 0 : 1;
2784 return int_reg[has_zr][1][regno];
2787 /* Get the name of the integer offset register in OPND, using the shift type
2788 to decide whether it's a word or doubleword. */
2790 static inline const char *
2791 get_offset_int_reg_name (const aarch64_opnd_info *opnd)
2793 switch (opnd->shifter.kind)
2795 case AARCH64_MOD_UXTW:
2796 case AARCH64_MOD_SXTW:
2797 return get_int_reg_name (opnd->addr.offset.regno, AARCH64_OPND_QLF_W, 0);
2799 case AARCH64_MOD_LSL:
2800 case AARCH64_MOD_SXTX:
2801 return get_int_reg_name (opnd->addr.offset.regno, AARCH64_OPND_QLF_X, 0);
2808 /* Get the name of the SVE vector offset register in OPND, using the operand
2809 qualifier to decide whether the suffix should be .S or .D. */
2811 static inline const char *
2812 get_addr_sve_reg_name (int regno, aarch64_opnd_qualifier_t qualifier)
2814 assert (qualifier == AARCH64_OPND_QLF_S_S
2815 || qualifier == AARCH64_OPND_QLF_S_D);
2816 return sve_reg[qualifier == AARCH64_OPND_QLF_S_D][regno];
2819 /* Types for expanding an encoded 8-bit value to a floating-point value. */
2839 /* IMM8 is an 8-bit floating-point constant with sign, 3-bit exponent and
2840 normalized 4 bits of precision, encoded in "a:b:c:d:e:f:g:h" or FLD_imm8
2841 (depending on the type of the instruction). IMM8 will be expanded to a
2842 single-precision floating-point value (SIZE == 4) or a double-precision
2843 floating-point value (SIZE == 8). A half-precision floating-point value
2844 (SIZE == 2) is expanded to a single-precision floating-point value. The
2845 expanded value is returned. */
2848 expand_fp_imm (int size, uint32_t imm8)
2851 uint32_t imm8_7, imm8_6_0, imm8_6, imm8_6_repl4;
2853 imm8_7 = (imm8 >> 7) & 0x01; /* imm8<7> */
2854 imm8_6_0 = imm8 & 0x7f; /* imm8<6:0> */
2855 imm8_6 = imm8_6_0 >> 6; /* imm8<6> */
2856 imm8_6_repl4 = (imm8_6 << 3) | (imm8_6 << 2)
2857 | (imm8_6 << 1) | imm8_6; /* Replicate(imm8<6>,4) */
2860 imm = (imm8_7 << (63-32)) /* imm8<7> */
2861 | ((imm8_6 ^ 1) << (62-32)) /* NOT(imm8<6) */
2862 | (imm8_6_repl4 << (58-32)) | (imm8_6 << (57-32))
2863 | (imm8_6 << (56-32)) | (imm8_6 << (55-32)) /* Replicate(imm8<6>,7) */
2864 | (imm8_6_0 << (48-32)); /* imm8<6>:imm8<5:0> */
2867 else if (size == 4 || size == 2)
2869 imm = (imm8_7 << 31) /* imm8<7> */
2870 | ((imm8_6 ^ 1) << 30) /* NOT(imm8<6>) */
2871 | (imm8_6_repl4 << 26) /* Replicate(imm8<6>,4) */
2872 | (imm8_6_0 << 19); /* imm8<6>:imm8<5:0> */
2876 /* An unsupported size. */
2883 /* Produce the string representation of the register list operand *OPND
2884 in the buffer pointed by BUF of size SIZE. PREFIX is the part of
2885 the register name that comes before the register number, such as "v". */
2887 print_register_list (char *buf, size_t size, const aarch64_opnd_info *opnd,
2890 const int num_regs = opnd->reglist.num_regs;
2891 const int first_reg = opnd->reglist.first_regno;
2892 const int last_reg = (first_reg + num_regs - 1) & 0x1f;
2893 const char *qlf_name = aarch64_get_qualifier_name (opnd->qualifier);
2894 char tb[8]; /* Temporary buffer. */
2896 assert (opnd->type != AARCH64_OPND_LEt || opnd->reglist.has_index);
2897 assert (num_regs >= 1 && num_regs <= 4);
2899 /* Prepare the index if any. */
2900 if (opnd->reglist.has_index)
2901 /* PR 21096: The %100 is to silence a warning about possible truncation. */
2902 snprintf (tb, 8, "[%" PRIi64 "]", (opnd->reglist.index % 100));
2906 /* The hyphenated form is preferred for disassembly if there are
2907 more than two registers in the list, and the register numbers
2908 are monotonically increasing in increments of one. */
2909 if (num_regs > 2 && last_reg > first_reg)
2910 snprintf (buf, size, "{%s%d.%s-%s%d.%s}%s", prefix, first_reg, qlf_name,
2911 prefix, last_reg, qlf_name, tb);
2914 const int reg0 = first_reg;
2915 const int reg1 = (first_reg + 1) & 0x1f;
2916 const int reg2 = (first_reg + 2) & 0x1f;
2917 const int reg3 = (first_reg + 3) & 0x1f;
2922 snprintf (buf, size, "{%s%d.%s}%s", prefix, reg0, qlf_name, tb);
2925 snprintf (buf, size, "{%s%d.%s, %s%d.%s}%s", prefix, reg0, qlf_name,
2926 prefix, reg1, qlf_name, tb);
2929 snprintf (buf, size, "{%s%d.%s, %s%d.%s, %s%d.%s}%s",
2930 prefix, reg0, qlf_name, prefix, reg1, qlf_name,
2931 prefix, reg2, qlf_name, tb);
2934 snprintf (buf, size, "{%s%d.%s, %s%d.%s, %s%d.%s, %s%d.%s}%s",
2935 prefix, reg0, qlf_name, prefix, reg1, qlf_name,
2936 prefix, reg2, qlf_name, prefix, reg3, qlf_name, tb);
2942 /* Print the register+immediate address in OPND to BUF, which has SIZE
2943 characters. BASE is the name of the base register. */
2946 print_immediate_offset_address (char *buf, size_t size,
2947 const aarch64_opnd_info *opnd,
2950 if (opnd->addr.writeback)
2952 if (opnd->addr.preind)
2953 snprintf (buf, size, "[%s, #%d]!", base, opnd->addr.offset.imm);
2955 snprintf (buf, size, "[%s], #%d", base, opnd->addr.offset.imm);
2959 if (opnd->shifter.operator_present)
2961 assert (opnd->shifter.kind == AARCH64_MOD_MUL_VL);
2962 snprintf (buf, size, "[%s, #%d, mul vl]",
2963 base, opnd->addr.offset.imm);
2965 else if (opnd->addr.offset.imm)
2966 snprintf (buf, size, "[%s, #%d]", base, opnd->addr.offset.imm);
2968 snprintf (buf, size, "[%s]", base);
2972 /* Produce the string representation of the register offset address operand
2973 *OPND in the buffer pointed by BUF of size SIZE. BASE and OFFSET are
2974 the names of the base and offset registers. */
2976 print_register_offset_address (char *buf, size_t size,
2977 const aarch64_opnd_info *opnd,
2978 const char *base, const char *offset)
2980 char tb[16]; /* Temporary buffer. */
2981 bfd_boolean print_extend_p = TRUE;
2982 bfd_boolean print_amount_p = TRUE;
2983 const char *shift_name = aarch64_operand_modifiers[opnd->shifter.kind].name;
2985 if (!opnd->shifter.amount && (opnd->qualifier != AARCH64_OPND_QLF_S_B
2986 || !opnd->shifter.amount_present))
2988 /* Not print the shift/extend amount when the amount is zero and
2989 when it is not the special case of 8-bit load/store instruction. */
2990 print_amount_p = FALSE;
2991 /* Likewise, no need to print the shift operator LSL in such a
2993 if (opnd->shifter.kind == AARCH64_MOD_LSL)
2994 print_extend_p = FALSE;
2997 /* Prepare for the extend/shift. */
3001 snprintf (tb, sizeof (tb), ", %s #%" PRIi64, shift_name,
3002 /* PR 21096: The %100 is to silence a warning about possible truncation. */
3003 (opnd->shifter.amount % 100));
3005 snprintf (tb, sizeof (tb), ", %s", shift_name);
3010 snprintf (buf, size, "[%s, %s%s]", base, offset, tb);
3013 /* Generate the string representation of the operand OPNDS[IDX] for OPCODE
3014 in *BUF. The caller should pass in the maximum size of *BUF in SIZE.
3015 PC, PCREL_P and ADDRESS are used to pass in and return information about
3016 the PC-relative address calculation, where the PC value is passed in
3017 PC. If the operand is pc-relative related, *PCREL_P (if PCREL_P non-NULL)
3018 will return 1 and *ADDRESS (if ADDRESS non-NULL) will return the
3019 calculated address; otherwise, *PCREL_P (if PCREL_P non-NULL) returns 0.
3021 The function serves both the disassembler and the assembler diagnostics
3022 issuer, which is the reason why it lives in this file. */
3025 aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
3026 const aarch64_opcode *opcode,
3027 const aarch64_opnd_info *opnds, int idx, int *pcrel_p,
3030 unsigned int i, num_conds;
3031 const char *name = NULL;
3032 const aarch64_opnd_info *opnd = opnds + idx;
3033 enum aarch64_modifier_kind kind;
3034 uint64_t addr, enum_value;
3042 case AARCH64_OPND_Rd:
3043 case AARCH64_OPND_Rn:
3044 case AARCH64_OPND_Rm:
3045 case AARCH64_OPND_Rt:
3046 case AARCH64_OPND_Rt2:
3047 case AARCH64_OPND_Rs:
3048 case AARCH64_OPND_Ra:
3049 case AARCH64_OPND_Rt_SYS:
3050 case AARCH64_OPND_PAIRREG:
3051 case AARCH64_OPND_SVE_Rm:
3052 /* The optional-ness of <Xt> in e.g. IC <ic_op>{, <Xt>} is determined by
3053 the <ic_op>, therefore we we use opnd->present to override the
3054 generic optional-ness information. */
3055 if (opnd->type == AARCH64_OPND_Rt_SYS)
3060 /* Omit the operand, e.g. RET. */
3061 else if (optional_operand_p (opcode, idx)
3063 == get_optional_operand_default_value (opcode)))
3065 assert (opnd->qualifier == AARCH64_OPND_QLF_W
3066 || opnd->qualifier == AARCH64_OPND_QLF_X);
3067 snprintf (buf, size, "%s",
3068 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
3071 case AARCH64_OPND_Rd_SP:
3072 case AARCH64_OPND_Rn_SP:
3073 case AARCH64_OPND_SVE_Rn_SP:
3074 case AARCH64_OPND_Rm_SP:
3075 assert (opnd->qualifier == AARCH64_OPND_QLF_W
3076 || opnd->qualifier == AARCH64_OPND_QLF_WSP
3077 || opnd->qualifier == AARCH64_OPND_QLF_X
3078 || opnd->qualifier == AARCH64_OPND_QLF_SP);
3079 snprintf (buf, size, "%s",
3080 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 1));
3083 case AARCH64_OPND_Rm_EXT:
3084 kind = opnd->shifter.kind;
3085 assert (idx == 1 || idx == 2);
3086 if ((aarch64_stack_pointer_p (opnds)
3087 || (idx == 2 && aarch64_stack_pointer_p (opnds + 1)))
3088 && ((opnd->qualifier == AARCH64_OPND_QLF_W
3089 && opnds[0].qualifier == AARCH64_OPND_QLF_W
3090 && kind == AARCH64_MOD_UXTW)
3091 || (opnd->qualifier == AARCH64_OPND_QLF_X
3092 && kind == AARCH64_MOD_UXTX)))
3094 /* 'LSL' is the preferred form in this case. */
3095 kind = AARCH64_MOD_LSL;
3096 if (opnd->shifter.amount == 0)
3098 /* Shifter omitted. */
3099 snprintf (buf, size, "%s",
3100 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
3104 if (opnd->shifter.amount)
3105 snprintf (buf, size, "%s, %s #%" PRIi64,
3106 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
3107 aarch64_operand_modifiers[kind].name,
3108 opnd->shifter.amount);
3110 snprintf (buf, size, "%s, %s",
3111 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
3112 aarch64_operand_modifiers[kind].name);
3115 case AARCH64_OPND_Rm_SFT:
3116 assert (opnd->qualifier == AARCH64_OPND_QLF_W
3117 || opnd->qualifier == AARCH64_OPND_QLF_X);
3118 if (opnd->shifter.amount == 0 && opnd->shifter.kind == AARCH64_MOD_LSL)
3119 snprintf (buf, size, "%s",
3120 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
3122 snprintf (buf, size, "%s, %s #%" PRIi64,
3123 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
3124 aarch64_operand_modifiers[opnd->shifter.kind].name,
3125 opnd->shifter.amount);
3128 case AARCH64_OPND_Fd:
3129 case AARCH64_OPND_Fn:
3130 case AARCH64_OPND_Fm:
3131 case AARCH64_OPND_Fa:
3132 case AARCH64_OPND_Ft:
3133 case AARCH64_OPND_Ft2:
3134 case AARCH64_OPND_Sd:
3135 case AARCH64_OPND_Sn:
3136 case AARCH64_OPND_Sm:
3137 case AARCH64_OPND_SVE_VZn:
3138 case AARCH64_OPND_SVE_Vd:
3139 case AARCH64_OPND_SVE_Vm:
3140 case AARCH64_OPND_SVE_Vn:
3141 snprintf (buf, size, "%s%d", aarch64_get_qualifier_name (opnd->qualifier),
3145 case AARCH64_OPND_Vd:
3146 case AARCH64_OPND_Vn:
3147 case AARCH64_OPND_Vm:
3148 snprintf (buf, size, "v%d.%s", opnd->reg.regno,
3149 aarch64_get_qualifier_name (opnd->qualifier));
3152 case AARCH64_OPND_Ed:
3153 case AARCH64_OPND_En:
3154 case AARCH64_OPND_Em:
3155 snprintf (buf, size, "v%d.%s[%" PRIi64 "]", opnd->reglane.regno,
3156 aarch64_get_qualifier_name (opnd->qualifier),
3157 opnd->reglane.index);
3160 case AARCH64_OPND_VdD1:
3161 case AARCH64_OPND_VnD1:
3162 snprintf (buf, size, "v%d.d[1]", opnd->reg.regno);
3165 case AARCH64_OPND_LVn:
3166 case AARCH64_OPND_LVt:
3167 case AARCH64_OPND_LVt_AL:
3168 case AARCH64_OPND_LEt:
3169 print_register_list (buf, size, opnd, "v");
3172 case AARCH64_OPND_SVE_Pd:
3173 case AARCH64_OPND_SVE_Pg3:
3174 case AARCH64_OPND_SVE_Pg4_5:
3175 case AARCH64_OPND_SVE_Pg4_10:
3176 case AARCH64_OPND_SVE_Pg4_16:
3177 case AARCH64_OPND_SVE_Pm:
3178 case AARCH64_OPND_SVE_Pn:
3179 case AARCH64_OPND_SVE_Pt:
3180 if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
3181 snprintf (buf, size, "p%d", opnd->reg.regno);
3182 else if (opnd->qualifier == AARCH64_OPND_QLF_P_Z
3183 || opnd->qualifier == AARCH64_OPND_QLF_P_M)
3184 snprintf (buf, size, "p%d/%s", opnd->reg.regno,
3185 aarch64_get_qualifier_name (opnd->qualifier));
3187 snprintf (buf, size, "p%d.%s", opnd->reg.regno,
3188 aarch64_get_qualifier_name (opnd->qualifier));
3191 case AARCH64_OPND_SVE_Za_5:
3192 case AARCH64_OPND_SVE_Za_16:
3193 case AARCH64_OPND_SVE_Zd:
3194 case AARCH64_OPND_SVE_Zm_5:
3195 case AARCH64_OPND_SVE_Zm_16:
3196 case AARCH64_OPND_SVE_Zn:
3197 case AARCH64_OPND_SVE_Zt:
3198 if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
3199 snprintf (buf, size, "z%d", opnd->reg.regno);
3201 snprintf (buf, size, "z%d.%s", opnd->reg.regno,
3202 aarch64_get_qualifier_name (opnd->qualifier));
3205 case AARCH64_OPND_SVE_ZnxN:
3206 case AARCH64_OPND_SVE_ZtxN:
3207 print_register_list (buf, size, opnd, "z");
3210 case AARCH64_OPND_SVE_Zm3_INDEX:
3211 case AARCH64_OPND_SVE_Zm3_22_INDEX:
3212 case AARCH64_OPND_SVE_Zm4_INDEX:
3213 case AARCH64_OPND_SVE_Zn_INDEX:
3214 snprintf (buf, size, "z%d.%s[%" PRIi64 "]", opnd->reglane.regno,
3215 aarch64_get_qualifier_name (opnd->qualifier),
3216 opnd->reglane.index);
3219 case AARCH64_OPND_CRn:
3220 case AARCH64_OPND_CRm:
3221 snprintf (buf, size, "C%" PRIi64, opnd->imm.value);
3224 case AARCH64_OPND_IDX:
3225 case AARCH64_OPND_IMM:
3226 case AARCH64_OPND_WIDTH:
3227 case AARCH64_OPND_UIMM3_OP1:
3228 case AARCH64_OPND_UIMM3_OP2:
3229 case AARCH64_OPND_BIT_NUM:
3230 case AARCH64_OPND_IMM_VLSL:
3231 case AARCH64_OPND_IMM_VLSR:
3232 case AARCH64_OPND_SHLL_IMM:
3233 case AARCH64_OPND_IMM0:
3234 case AARCH64_OPND_IMMR:
3235 case AARCH64_OPND_IMMS:
3236 case AARCH64_OPND_FBITS:
3237 case AARCH64_OPND_SIMM5:
3238 case AARCH64_OPND_SVE_SHLIMM_PRED:
3239 case AARCH64_OPND_SVE_SHLIMM_UNPRED:
3240 case AARCH64_OPND_SVE_SHRIMM_PRED:
3241 case AARCH64_OPND_SVE_SHRIMM_UNPRED:
3242 case AARCH64_OPND_SVE_SIMM5:
3243 case AARCH64_OPND_SVE_SIMM5B:
3244 case AARCH64_OPND_SVE_SIMM6:
3245 case AARCH64_OPND_SVE_SIMM8:
3246 case AARCH64_OPND_SVE_UIMM3:
3247 case AARCH64_OPND_SVE_UIMM7:
3248 case AARCH64_OPND_SVE_UIMM8:
3249 case AARCH64_OPND_SVE_UIMM8_53:
3250 case AARCH64_OPND_IMM_ROT1:
3251 case AARCH64_OPND_IMM_ROT2:
3252 case AARCH64_OPND_IMM_ROT3:
3253 case AARCH64_OPND_SVE_IMM_ROT1:
3254 case AARCH64_OPND_SVE_IMM_ROT2:
3255 snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
3258 case AARCH64_OPND_SVE_I1_HALF_ONE:
3259 case AARCH64_OPND_SVE_I1_HALF_TWO:
3260 case AARCH64_OPND_SVE_I1_ZERO_ONE:
3263 c.i = opnd->imm.value;
3264 snprintf (buf, size, "#%.1f", c.f);
3268 case AARCH64_OPND_SVE_PATTERN:
3269 if (optional_operand_p (opcode, idx)
3270 && opnd->imm.value == get_optional_operand_default_value (opcode))
3272 enum_value = opnd->imm.value;
3273 assert (enum_value < ARRAY_SIZE (aarch64_sve_pattern_array));
3274 if (aarch64_sve_pattern_array[enum_value])
3275 snprintf (buf, size, "%s", aarch64_sve_pattern_array[enum_value]);
3277 snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
3280 case AARCH64_OPND_SVE_PATTERN_SCALED:
3281 if (optional_operand_p (opcode, idx)
3282 && !opnd->shifter.operator_present
3283 && opnd->imm.value == get_optional_operand_default_value (opcode))
3285 enum_value = opnd->imm.value;
3286 assert (enum_value < ARRAY_SIZE (aarch64_sve_pattern_array));
3287 if (aarch64_sve_pattern_array[opnd->imm.value])
3288 snprintf (buf, size, "%s", aarch64_sve_pattern_array[opnd->imm.value]);
3290 snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
3291 if (opnd->shifter.operator_present)
3293 size_t len = strlen (buf);
3294 snprintf (buf + len, size - len, ", %s #%" PRIi64,
3295 aarch64_operand_modifiers[opnd->shifter.kind].name,
3296 opnd->shifter.amount);
3300 case AARCH64_OPND_SVE_PRFOP:
3301 enum_value = opnd->imm.value;
3302 assert (enum_value < ARRAY_SIZE (aarch64_sve_prfop_array));
3303 if (aarch64_sve_prfop_array[enum_value])
3304 snprintf (buf, size, "%s", aarch64_sve_prfop_array[enum_value]);
3306 snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
3309 case AARCH64_OPND_IMM_MOV:
3310 switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
3312 case 4: /* e.g. MOV Wd, #<imm32>. */
3314 int imm32 = opnd->imm.value;
3315 snprintf (buf, size, "#0x%-20x\t// #%d", imm32, imm32);
3318 case 8: /* e.g. MOV Xd, #<imm64>. */
3319 snprintf (buf, size, "#0x%-20" PRIx64 "\t// #%" PRIi64,
3320 opnd->imm.value, opnd->imm.value);
3322 default: assert (0);
3326 case AARCH64_OPND_FPIMM0:
3327 snprintf (buf, size, "#0.0");
3330 case AARCH64_OPND_LIMM:
3331 case AARCH64_OPND_AIMM:
3332 case AARCH64_OPND_HALF:
3333 case AARCH64_OPND_SVE_INV_LIMM:
3334 case AARCH64_OPND_SVE_LIMM:
3335 case AARCH64_OPND_SVE_LIMM_MOV:
3336 if (opnd->shifter.amount)
3337 snprintf (buf, size, "#0x%" PRIx64 ", lsl #%" PRIi64, opnd->imm.value,
3338 opnd->shifter.amount);
3340 snprintf (buf, size, "#0x%" PRIx64, opnd->imm.value);
3343 case AARCH64_OPND_SIMD_IMM:
3344 case AARCH64_OPND_SIMD_IMM_SFT:
3345 if ((! opnd->shifter.amount && opnd->shifter.kind == AARCH64_MOD_LSL)
3346 || opnd->shifter.kind == AARCH64_MOD_NONE)
3347 snprintf (buf, size, "#0x%" PRIx64, opnd->imm.value);
3349 snprintf (buf, size, "#0x%" PRIx64 ", %s #%" PRIi64, opnd->imm.value,
3350 aarch64_operand_modifiers[opnd->shifter.kind].name,
3351 opnd->shifter.amount);
3354 case AARCH64_OPND_SVE_AIMM:
3355 case AARCH64_OPND_SVE_ASIMM:
3356 if (opnd->shifter.amount)
3357 snprintf (buf, size, "#%" PRIi64 ", lsl #%" PRIi64, opnd->imm.value,
3358 opnd->shifter.amount);
3360 snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
3363 case AARCH64_OPND_FPIMM:
3364 case AARCH64_OPND_SIMD_FPIMM:
3365 case AARCH64_OPND_SVE_FPIMM8:
3366 switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
3368 case 2: /* e.g. FMOV <Hd>, #<imm>. */
3371 c.i = expand_fp_imm (2, opnd->imm.value);
3372 snprintf (buf, size, "#%.18e", c.f);
3375 case 4: /* e.g. FMOV <Vd>.4S, #<imm>. */
3378 c.i = expand_fp_imm (4, opnd->imm.value);
3379 snprintf (buf, size, "#%.18e", c.f);
3382 case 8: /* e.g. FMOV <Sd>, #<imm>. */
3385 c.i = expand_fp_imm (8, opnd->imm.value);
3386 snprintf (buf, size, "#%.18e", c.d);
3389 default: assert (0);
3393 case AARCH64_OPND_CCMP_IMM:
3394 case AARCH64_OPND_NZCV:
3395 case AARCH64_OPND_EXCEPTION:
3396 case AARCH64_OPND_UIMM4:
3397 case AARCH64_OPND_UIMM7:
3398 if (optional_operand_p (opcode, idx) == TRUE
3399 && (opnd->imm.value ==
3400 (int64_t) get_optional_operand_default_value (opcode)))
3401 /* Omit the operand, e.g. DCPS1. */
3403 snprintf (buf, size, "#0x%x", (unsigned int)opnd->imm.value);
3406 case AARCH64_OPND_COND:
3407 case AARCH64_OPND_COND1:
3408 snprintf (buf, size, "%s", opnd->cond->names[0]);
3409 num_conds = ARRAY_SIZE (opnd->cond->names);
3410 for (i = 1; i < num_conds && opnd->cond->names[i]; ++i)
3412 size_t len = strlen (buf);
3414 snprintf (buf + len, size - len, " // %s = %s",
3415 opnd->cond->names[0], opnd->cond->names[i]);
3417 snprintf (buf + len, size - len, ", %s",
3418 opnd->cond->names[i]);
3422 case AARCH64_OPND_ADDR_ADRP:
3423 addr = ((pc + AARCH64_PCREL_OFFSET) & ~(uint64_t)0xfff)
3429 /* This is not necessary during the disassembling, as print_address_func
3430 in the disassemble_info will take care of the printing. But some
3431 other callers may be still interested in getting the string in *STR,
3432 so here we do snprintf regardless. */
3433 snprintf (buf, size, "#0x%" PRIx64, addr);
3436 case AARCH64_OPND_ADDR_PCREL14:
3437 case AARCH64_OPND_ADDR_PCREL19:
3438 case AARCH64_OPND_ADDR_PCREL21:
3439 case AARCH64_OPND_ADDR_PCREL26:
3440 addr = pc + AARCH64_PCREL_OFFSET + opnd->imm.value;
3445 /* This is not necessary during the disassembling, as print_address_func
3446 in the disassemble_info will take care of the printing. But some
3447 other callers may be still interested in getting the string in *STR,
3448 so here we do snprintf regardless. */
3449 snprintf (buf, size, "#0x%" PRIx64, addr);
3452 case AARCH64_OPND_ADDR_SIMPLE:
3453 case AARCH64_OPND_SIMD_ADDR_SIMPLE:
3454 case AARCH64_OPND_SIMD_ADDR_POST:
3455 name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
3456 if (opnd->type == AARCH64_OPND_SIMD_ADDR_POST)
3458 if (opnd->addr.offset.is_reg)
3459 snprintf (buf, size, "[%s], x%d", name, opnd->addr.offset.regno);
3461 snprintf (buf, size, "[%s], #%d", name, opnd->addr.offset.imm);
3464 snprintf (buf, size, "[%s]", name);
3467 case AARCH64_OPND_ADDR_REGOFF:
3468 case AARCH64_OPND_SVE_ADDR_RR:
3469 case AARCH64_OPND_SVE_ADDR_RR_LSL1:
3470 case AARCH64_OPND_SVE_ADDR_RR_LSL2:
3471 case AARCH64_OPND_SVE_ADDR_RR_LSL3:
3472 case AARCH64_OPND_SVE_ADDR_RX:
3473 case AARCH64_OPND_SVE_ADDR_RX_LSL1:
3474 case AARCH64_OPND_SVE_ADDR_RX_LSL2:
3475 case AARCH64_OPND_SVE_ADDR_RX_LSL3:
3476 print_register_offset_address
3477 (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
3478 get_offset_int_reg_name (opnd));
3481 case AARCH64_OPND_SVE_ADDR_RZ:
3482 case AARCH64_OPND_SVE_ADDR_RZ_LSL1:
3483 case AARCH64_OPND_SVE_ADDR_RZ_LSL2:
3484 case AARCH64_OPND_SVE_ADDR_RZ_LSL3:
3485 case AARCH64_OPND_SVE_ADDR_RZ_XTW_14:
3486 case AARCH64_OPND_SVE_ADDR_RZ_XTW_22:
3487 case AARCH64_OPND_SVE_ADDR_RZ_XTW1_14:
3488 case AARCH64_OPND_SVE_ADDR_RZ_XTW1_22:
3489 case AARCH64_OPND_SVE_ADDR_RZ_XTW2_14:
3490 case AARCH64_OPND_SVE_ADDR_RZ_XTW2_22:
3491 case AARCH64_OPND_SVE_ADDR_RZ_XTW3_14:
3492 case AARCH64_OPND_SVE_ADDR_RZ_XTW3_22:
3493 print_register_offset_address
3494 (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
3495 get_addr_sve_reg_name (opnd->addr.offset.regno, opnd->qualifier));
3498 case AARCH64_OPND_ADDR_SIMM7:
3499 case AARCH64_OPND_ADDR_SIMM9:
3500 case AARCH64_OPND_ADDR_SIMM9_2:
3501 case AARCH64_OPND_ADDR_SIMM10:
3502 case AARCH64_OPND_SVE_ADDR_RI_S4x16:
3503 case AARCH64_OPND_SVE_ADDR_RI_S4xVL:
3504 case AARCH64_OPND_SVE_ADDR_RI_S4x2xVL:
3505 case AARCH64_OPND_SVE_ADDR_RI_S4x3xVL:
3506 case AARCH64_OPND_SVE_ADDR_RI_S4x4xVL:
3507 case AARCH64_OPND_SVE_ADDR_RI_S6xVL:
3508 case AARCH64_OPND_SVE_ADDR_RI_S9xVL:
3509 case AARCH64_OPND_SVE_ADDR_RI_U6:
3510 case AARCH64_OPND_SVE_ADDR_RI_U6x2:
3511 case AARCH64_OPND_SVE_ADDR_RI_U6x4:
3512 case AARCH64_OPND_SVE_ADDR_RI_U6x8:
3513 print_immediate_offset_address
3514 (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1));
3517 case AARCH64_OPND_SVE_ADDR_ZI_U5:
3518 case AARCH64_OPND_SVE_ADDR_ZI_U5x2:
3519 case AARCH64_OPND_SVE_ADDR_ZI_U5x4:
3520 case AARCH64_OPND_SVE_ADDR_ZI_U5x8:
3521 print_immediate_offset_address
3523 get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier));
3526 case AARCH64_OPND_SVE_ADDR_ZZ_LSL:
3527 case AARCH64_OPND_SVE_ADDR_ZZ_SXTW:
3528 case AARCH64_OPND_SVE_ADDR_ZZ_UXTW:
3529 print_register_offset_address
3531 get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier),
3532 get_addr_sve_reg_name (opnd->addr.offset.regno, opnd->qualifier));
3535 case AARCH64_OPND_ADDR_UIMM12:
3536 name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
3537 if (opnd->addr.offset.imm)
3538 snprintf (buf, size, "[%s, #%d]", name, opnd->addr.offset.imm);
3540 snprintf (buf, size, "[%s]", name);
3543 case AARCH64_OPND_SYSREG:
3544 for (i = 0; aarch64_sys_regs[i].name; ++i)
3545 if (aarch64_sys_regs[i].value == opnd->sysreg
3546 && ! aarch64_sys_reg_deprecated_p (&aarch64_sys_regs[i]))
3548 if (aarch64_sys_regs[i].name)
3549 snprintf (buf, size, "%s", aarch64_sys_regs[i].name);
3552 /* Implementation defined system register. */
3553 unsigned int value = opnd->sysreg;
3554 snprintf (buf, size, "s%u_%u_c%u_c%u_%u", (value >> 14) & 0x3,
3555 (value >> 11) & 0x7, (value >> 7) & 0xf, (value >> 3) & 0xf,
3560 case AARCH64_OPND_PSTATEFIELD:
3561 for (i = 0; aarch64_pstatefields[i].name; ++i)
3562 if (aarch64_pstatefields[i].value == opnd->pstatefield)
3564 assert (aarch64_pstatefields[i].name);
3565 snprintf (buf, size, "%s", aarch64_pstatefields[i].name);
3568 case AARCH64_OPND_SYSREG_AT:
3569 case AARCH64_OPND_SYSREG_DC:
3570 case AARCH64_OPND_SYSREG_IC:
3571 case AARCH64_OPND_SYSREG_TLBI:
3572 snprintf (buf, size, "%s", opnd->sysins_op->name);
3575 case AARCH64_OPND_BARRIER:
3576 snprintf (buf, size, "%s", opnd->barrier->name);
3579 case AARCH64_OPND_BARRIER_ISB:
3580 /* Operand can be omitted, e.g. in DCPS1. */
3581 if (! optional_operand_p (opcode, idx)
3582 || (opnd->barrier->value
3583 != get_optional_operand_default_value (opcode)))
3584 snprintf (buf, size, "#0x%x", opnd->barrier->value);
3587 case AARCH64_OPND_PRFOP:
3588 if (opnd->prfop->name != NULL)
3589 snprintf (buf, size, "%s", opnd->prfop->name);
3591 snprintf (buf, size, "#0x%02x", opnd->prfop->value);
3594 case AARCH64_OPND_BARRIER_PSB:
3595 snprintf (buf, size, "%s", opnd->hint_option->name);
3603 #define CPENC(op0,op1,crn,crm,op2) \
3604 ((((op0) << 19) | ((op1) << 16) | ((crn) << 12) | ((crm) << 8) | ((op2) << 5)) >> 5)
3605 /* for 3.9.3 Instructions for Accessing Special Purpose Registers */
3606 #define CPEN_(op1,crm,op2) CPENC(3,(op1),4,(crm),(op2))
3607 /* for 3.9.10 System Instructions */
3608 #define CPENS(op1,crn,crm,op2) CPENC(1,(op1),(crn),(crm),(op2))
3630 #define F_DEPRECATED 0x1 /* Deprecated system register. */
3635 #define F_ARCHEXT 0x2 /* Architecture dependent system register. */
3640 #define F_HASXT 0x4 /* System instruction register <Xt>
3644 /* TODO there are two more issues need to be resolved
3645 1. handle read-only and write-only system registers
3646 2. handle cpu-implementation-defined system registers. */
3647 const aarch64_sys_reg aarch64_sys_regs [] =
3649 { "spsr_el1", CPEN_(0,C0,0), 0 }, /* = spsr_svc */
3650 { "spsr_el12", CPEN_ (5, C0, 0), F_ARCHEXT },
3651 { "elr_el1", CPEN_(0,C0,1), 0 },
3652 { "elr_el12", CPEN_ (5, C0, 1), F_ARCHEXT },
3653 { "sp_el0", CPEN_(0,C1,0), 0 },
3654 { "spsel", CPEN_(0,C2,0), 0 },
3655 { "daif", CPEN_(3,C2,1), 0 },
3656 { "currentel", CPEN_(0,C2,2), 0 }, /* RO */
3657 { "pan", CPEN_(0,C2,3), F_ARCHEXT },
3658 { "uao", CPEN_ (0, C2, 4), F_ARCHEXT },
3659 { "nzcv", CPEN_(3,C2,0), 0 },
3660 { "fpcr", CPEN_(3,C4,0), 0 },
3661 { "fpsr", CPEN_(3,C4,1), 0 },
3662 { "dspsr_el0", CPEN_(3,C5,0), 0 },
3663 { "dlr_el0", CPEN_(3,C5,1), 0 },
3664 { "spsr_el2", CPEN_(4,C0,0), 0 }, /* = spsr_hyp */
3665 { "elr_el2", CPEN_(4,C0,1), 0 },
3666 { "sp_el1", CPEN_(4,C1,0), 0 },
3667 { "spsr_irq", CPEN_(4,C3,0), 0 },
3668 { "spsr_abt", CPEN_(4,C3,1), 0 },
3669 { "spsr_und", CPEN_(4,C3,2), 0 },
3670 { "spsr_fiq", CPEN_(4,C3,3), 0 },
3671 { "spsr_el3", CPEN_(6,C0,0), 0 },
3672 { "elr_el3", CPEN_(6,C0,1), 0 },
3673 { "sp_el2", CPEN_(6,C1,0), 0 },
3674 { "spsr_svc", CPEN_(0,C0,0), F_DEPRECATED }, /* = spsr_el1 */
3675 { "spsr_hyp", CPEN_(4,C0,0), F_DEPRECATED }, /* = spsr_el2 */
3676 { "midr_el1", CPENC(3,0,C0,C0,0), 0 }, /* RO */
3677 { "ctr_el0", CPENC(3,3,C0,C0,1), 0 }, /* RO */
3678 { "mpidr_el1", CPENC(3,0,C0,C0,5), 0 }, /* RO */
3679 { "revidr_el1", CPENC(3,0,C0,C0,6), 0 }, /* RO */
3680 { "aidr_el1", CPENC(3,1,C0,C0,7), 0 }, /* RO */
3681 { "dczid_el0", CPENC(3,3,C0,C0,7), 0 }, /* RO */
3682 { "id_dfr0_el1", CPENC(3,0,C0,C1,2), 0 }, /* RO */
3683 { "id_pfr0_el1", CPENC(3,0,C0,C1,0), 0 }, /* RO */
3684 { "id_pfr1_el1", CPENC(3,0,C0,C1,1), 0 }, /* RO */
3685 { "id_afr0_el1", CPENC(3,0,C0,C1,3), 0 }, /* RO */
3686 { "id_mmfr0_el1", CPENC(3,0,C0,C1,4), 0 }, /* RO */
3687 { "id_mmfr1_el1", CPENC(3,0,C0,C1,5), 0 }, /* RO */
3688 { "id_mmfr2_el1", CPENC(3,0,C0,C1,6), 0 }, /* RO */
3689 { "id_mmfr3_el1", CPENC(3,0,C0,C1,7), 0 }, /* RO */
3690 { "id_mmfr4_el1", CPENC(3,0,C0,C2,6), 0 }, /* RO */
3691 { "id_isar0_el1", CPENC(3,0,C0,C2,0), 0 }, /* RO */
3692 { "id_isar1_el1", CPENC(3,0,C0,C2,1), 0 }, /* RO */
3693 { "id_isar2_el1", CPENC(3,0,C0,C2,2), 0 }, /* RO */
3694 { "id_isar3_el1", CPENC(3,0,C0,C2,3), 0 }, /* RO */
3695 { "id_isar4_el1", CPENC(3,0,C0,C2,4), 0 }, /* RO */
3696 { "id_isar5_el1", CPENC(3,0,C0,C2,5), 0 }, /* RO */
3697 { "mvfr0_el1", CPENC(3,0,C0,C3,0), 0 }, /* RO */
3698 { "mvfr1_el1", CPENC(3,0,C0,C3,1), 0 }, /* RO */
3699 { "mvfr2_el1", CPENC(3,0,C0,C3,2), 0 }, /* RO */
3700 { "ccsidr_el1", CPENC(3,1,C0,C0,0), 0 }, /* RO */
3701 { "id_aa64pfr0_el1", CPENC(3,0,C0,C4,0), 0 }, /* RO */
3702 { "id_aa64pfr1_el1", CPENC(3,0,C0,C4,1), 0 }, /* RO */
3703 { "id_aa64dfr0_el1", CPENC(3,0,C0,C5,0), 0 }, /* RO */
3704 { "id_aa64dfr1_el1", CPENC(3,0,C0,C5,1), 0 }, /* RO */
3705 { "id_aa64isar0_el1", CPENC(3,0,C0,C6,0), 0 }, /* RO */
3706 { "id_aa64isar1_el1", CPENC(3,0,C0,C6,1), 0 }, /* RO */
3707 { "id_aa64mmfr0_el1", CPENC(3,0,C0,C7,0), 0 }, /* RO */
3708 { "id_aa64mmfr1_el1", CPENC(3,0,C0,C7,1), 0 }, /* RO */
3709 { "id_aa64mmfr2_el1", CPENC (3, 0, C0, C7, 2), F_ARCHEXT }, /* RO */
3710 { "id_aa64afr0_el1", CPENC(3,0,C0,C5,4), 0 }, /* RO */
3711 { "id_aa64afr1_el1", CPENC(3,0,C0,C5,5), 0 }, /* RO */
3712 { "id_aa64zfr0_el1", CPENC (3, 0, C0, C4, 4), F_ARCHEXT }, /* RO */
3713 { "clidr_el1", CPENC(3,1,C0,C0,1), 0 }, /* RO */
3714 { "csselr_el1", CPENC(3,2,C0,C0,0), 0 }, /* RO */
3715 { "vpidr_el2", CPENC(3,4,C0,C0,0), 0 },
3716 { "vmpidr_el2", CPENC(3,4,C0,C0,5), 0 },
3717 { "sctlr_el1", CPENC(3,0,C1,C0,0), 0 },
3718 { "sctlr_el2", CPENC(3,4,C1,C0,0), 0 },
3719 { "sctlr_el3", CPENC(3,6,C1,C0,0), 0 },
3720 { "sctlr_el12", CPENC (3, 5, C1, C0, 0), F_ARCHEXT },
3721 { "actlr_el1", CPENC(3,0,C1,C0,1), 0 },
3722 { "actlr_el2", CPENC(3,4,C1,C0,1), 0 },
3723 { "actlr_el3", CPENC(3,6,C1,C0,1), 0 },
3724 { "cpacr_el1", CPENC(3,0,C1,C0,2), 0 },
3725 { "cpacr_el12", CPENC (3, 5, C1, C0, 2), F_ARCHEXT },
3726 { "cptr_el2", CPENC(3,4,C1,C1,2), 0 },
3727 { "cptr_el3", CPENC(3,6,C1,C1,2), 0 },
3728 { "scr_el3", CPENC(3,6,C1,C1,0), 0 },
3729 { "hcr_el2", CPENC(3,4,C1,C1,0), 0 },
3730 { "mdcr_el2", CPENC(3,4,C1,C1,1), 0 },
3731 { "mdcr_el3", CPENC(3,6,C1,C3,1), 0 },
3732 { "hstr_el2", CPENC(3,4,C1,C1,3), 0 },
3733 { "hacr_el2", CPENC(3,4,C1,C1,7), 0 },
3734 { "zcr_el1", CPENC (3, 0, C1, C2, 0), F_ARCHEXT },
3735 { "zcr_el12", CPENC (3, 5, C1, C2, 0), F_ARCHEXT },
3736 { "zcr_el2", CPENC (3, 4, C1, C2, 0), F_ARCHEXT },
3737 { "zcr_el3", CPENC (3, 6, C1, C2, 0), F_ARCHEXT },
3738 { "zidr_el1", CPENC (3, 0, C0, C0, 7), F_ARCHEXT },
3739 { "ttbr0_el1", CPENC(3,0,C2,C0,0), 0 },
3740 { "ttbr1_el1", CPENC(3,0,C2,C0,1), 0 },
3741 { "ttbr0_el2", CPENC(3,4,C2,C0,0), 0 },
3742 { "ttbr1_el2", CPENC (3, 4, C2, C0, 1), F_ARCHEXT },
3743 { "ttbr0_el3", CPENC(3,6,C2,C0,0), 0 },
3744 { "ttbr0_el12", CPENC (3, 5, C2, C0, 0), F_ARCHEXT },
3745 { "ttbr1_el12", CPENC (3, 5, C2, C0, 1), F_ARCHEXT },
3746 { "vttbr_el2", CPENC(3,4,C2,C1,0), 0 },
3747 { "tcr_el1", CPENC(3,0,C2,C0,2), 0 },
3748 { "tcr_el2", CPENC(3,4,C2,C0,2), 0 },
3749 { "tcr_el3", CPENC(3,6,C2,C0,2), 0 },
3750 { "tcr_el12", CPENC (3, 5, C2, C0, 2), F_ARCHEXT },
3751 { "vtcr_el2", CPENC(3,4,C2,C1,2), 0 },
3752 { "apiakeylo_el1", CPENC (3, 0, C2, C1, 0), F_ARCHEXT },
3753 { "apiakeyhi_el1", CPENC (3, 0, C2, C1, 1), F_ARCHEXT },
3754 { "apibkeylo_el1", CPENC (3, 0, C2, C1, 2), F_ARCHEXT },
3755 { "apibkeyhi_el1", CPENC (3, 0, C2, C1, 3), F_ARCHEXT },
3756 { "apdakeylo_el1", CPENC (3, 0, C2, C2, 0), F_ARCHEXT },
3757 { "apdakeyhi_el1", CPENC (3, 0, C2, C2, 1), F_ARCHEXT },
3758 { "apdbkeylo_el1", CPENC (3, 0, C2, C2, 2), F_ARCHEXT },
3759 { "apdbkeyhi_el1", CPENC (3, 0, C2, C2, 3), F_ARCHEXT },
3760 { "apgakeylo_el1", CPENC (3, 0, C2, C3, 0), F_ARCHEXT },
3761 { "apgakeyhi_el1", CPENC (3, 0, C2, C3, 1), F_ARCHEXT },
3762 { "afsr0_el1", CPENC(3,0,C5,C1,0), 0 },
3763 { "afsr1_el1", CPENC(3,0,C5,C1,1), 0 },
3764 { "afsr0_el2", CPENC(3,4,C5,C1,0), 0 },
3765 { "afsr1_el2", CPENC(3,4,C5,C1,1), 0 },
3766 { "afsr0_el3", CPENC(3,6,C5,C1,0), 0 },
3767 { "afsr0_el12", CPENC (3, 5, C5, C1, 0), F_ARCHEXT },
3768 { "afsr1_el3", CPENC(3,6,C5,C1,1), 0 },
3769 { "afsr1_el12", CPENC (3, 5, C5, C1, 1), F_ARCHEXT },
3770 { "esr_el1", CPENC(3,0,C5,C2,0), 0 },
3771 { "esr_el2", CPENC(3,4,C5,C2,0), 0 },
3772 { "esr_el3", CPENC(3,6,C5,C2,0), 0 },
3773 { "esr_el12", CPENC (3, 5, C5, C2, 0), F_ARCHEXT },
3774 { "vsesr_el2", CPENC (3, 4, C5, C2, 3), F_ARCHEXT }, /* RO */
3775 { "fpexc32_el2", CPENC(3,4,C5,C3,0), 0 },
3776 { "erridr_el1", CPENC (3, 0, C5, C3, 0), F_ARCHEXT }, /* RO */
3777 { "errselr_el1", CPENC (3, 0, C5, C3, 1), F_ARCHEXT },
3778 { "erxfr_el1", CPENC (3, 0, C5, C4, 0), F_ARCHEXT }, /* RO */
3779 { "erxctlr_el1", CPENC (3, 0, C5, C4, 1), F_ARCHEXT },
3780 { "erxstatus_el1", CPENC (3, 0, C5, C4, 2), F_ARCHEXT },
3781 { "erxaddr_el1", CPENC (3, 0, C5, C4, 3), F_ARCHEXT },
3782 { "erxmisc0_el1", CPENC (3, 0, C5, C5, 0), F_ARCHEXT },
3783 { "erxmisc1_el1", CPENC (3, 0, C5, C5, 1), F_ARCHEXT },
3784 { "far_el1", CPENC(3,0,C6,C0,0), 0 },
3785 { "far_el2", CPENC(3,4,C6,C0,0), 0 },
3786 { "far_el3", CPENC(3,6,C6,C0,0), 0 },
3787 { "far_el12", CPENC (3, 5, C6, C0, 0), F_ARCHEXT },
3788 { "hpfar_el2", CPENC(3,4,C6,C0,4), 0 },
3789 { "par_el1", CPENC(3,0,C7,C4,0), 0 },
3790 { "mair_el1", CPENC(3,0,C10,C2,0), 0 },
3791 { "mair_el2", CPENC(3,4,C10,C2,0), 0 },
3792 { "mair_el3", CPENC(3,6,C10,C2,0), 0 },
3793 { "mair_el12", CPENC (3, 5, C10, C2, 0), F_ARCHEXT },
3794 { "amair_el1", CPENC(3,0,C10,C3,0), 0 },
3795 { "amair_el2", CPENC(3,4,C10,C3,0), 0 },
3796 { "amair_el3", CPENC(3,6,C10,C3,0), 0 },
3797 { "amair_el12", CPENC (3, 5, C10, C3, 0), F_ARCHEXT },
3798 { "vbar_el1", CPENC(3,0,C12,C0,0), 0 },
3799 { "vbar_el2", CPENC(3,4,C12,C0,0), 0 },
3800 { "vbar_el3", CPENC(3,6,C12,C0,0), 0 },
3801 { "vbar_el12", CPENC (3, 5, C12, C0, 0), F_ARCHEXT },
3802 { "rvbar_el1", CPENC(3,0,C12,C0,1), 0 }, /* RO */
3803 { "rvbar_el2", CPENC(3,4,C12,C0,1), 0 }, /* RO */
3804 { "rvbar_el3", CPENC(3,6,C12,C0,1), 0 }, /* RO */
3805 { "rmr_el1", CPENC(3,0,C12,C0,2), 0 },
3806 { "rmr_el2", CPENC(3,4,C12,C0,2), 0 },
3807 { "rmr_el3", CPENC(3,6,C12,C0,2), 0 },
3808 { "isr_el1", CPENC(3,0,C12,C1,0), 0 }, /* RO */
3809 { "disr_el1", CPENC (3, 0, C12, C1, 1), F_ARCHEXT },
3810 { "vdisr_el2", CPENC (3, 4, C12, C1, 1), F_ARCHEXT },
3811 { "contextidr_el1", CPENC(3,0,C13,C0,1), 0 },
3812 { "contextidr_el2", CPENC (3, 4, C13, C0, 1), F_ARCHEXT },
3813 { "contextidr_el12", CPENC (3, 5, C13, C0, 1), F_ARCHEXT },
3814 { "tpidr_el0", CPENC(3,3,C13,C0,2), 0 },
3815 { "tpidrro_el0", CPENC(3,3,C13,C0,3), 0 }, /* RO */
3816 { "tpidr_el1", CPENC(3,0,C13,C0,4), 0 },
3817 { "tpidr_el2", CPENC(3,4,C13,C0,2), 0 },
3818 { "tpidr_el3", CPENC(3,6,C13,C0,2), 0 },
3819 { "teecr32_el1", CPENC(2,2,C0, C0,0), 0 }, /* See section 3.9.7.1 */
3820 { "cntfrq_el0", CPENC(3,3,C14,C0,0), 0 }, /* RO */
3821 { "cntpct_el0", CPENC(3,3,C14,C0,1), 0 }, /* RO */
3822 { "cntvct_el0", CPENC(3,3,C14,C0,2), 0 }, /* RO */
3823 { "cntvoff_el2", CPENC(3,4,C14,C0,3), 0 },
3824 { "cntkctl_el1", CPENC(3,0,C14,C1,0), 0 },
3825 { "cntkctl_el12", CPENC (3, 5, C14, C1, 0), F_ARCHEXT },
3826 { "cnthctl_el2", CPENC(3,4,C14,C1,0), 0 },
3827 { "cntp_tval_el0", CPENC(3,3,C14,C2,0), 0 },
3828 { "cntp_tval_el02", CPENC (3, 5, C14, C2, 0), F_ARCHEXT },
3829 { "cntp_ctl_el0", CPENC(3,3,C14,C2,1), 0 },
3830 { "cntp_ctl_el02", CPENC (3, 5, C14, C2, 1), F_ARCHEXT },
3831 { "cntp_cval_el0", CPENC(3,3,C14,C2,2), 0 },
3832 { "cntp_cval_el02", CPENC (3, 5, C14, C2, 2), F_ARCHEXT },
3833 { "cntv_tval_el0", CPENC(3,3,C14,C3,0), 0 },
3834 { "cntv_tval_el02", CPENC (3, 5, C14, C3, 0), F_ARCHEXT },
3835 { "cntv_ctl_el0", CPENC(3,3,C14,C3,1), 0 },
3836 { "cntv_ctl_el02", CPENC (3, 5, C14, C3, 1), F_ARCHEXT },
3837 { "cntv_cval_el0", CPENC(3,3,C14,C3,2), 0 },
3838 { "cntv_cval_el02", CPENC (3, 5, C14, C3, 2), F_ARCHEXT },
3839 { "cnthp_tval_el2", CPENC(3,4,C14,C2,0), 0 },
3840 { "cnthp_ctl_el2", CPENC(3,4,C14,C2,1), 0 },
3841 { "cnthp_cval_el2", CPENC(3,4,C14,C2,2), 0 },
3842 { "cntps_tval_el1", CPENC(3,7,C14,C2,0), 0 },
3843 { "cntps_ctl_el1", CPENC(3,7,C14,C2,1), 0 },
3844 { "cntps_cval_el1", CPENC(3,7,C14,C2,2), 0 },
3845 { "cnthv_tval_el2", CPENC (3, 4, C14, C3, 0), F_ARCHEXT },
3846 { "cnthv_ctl_el2", CPENC (3, 4, C14, C3, 1), F_ARCHEXT },
3847 { "cnthv_cval_el2", CPENC (3, 4, C14, C3, 2), F_ARCHEXT },
3848 { "dacr32_el2", CPENC(3,4,C3,C0,0), 0 },
3849 { "ifsr32_el2", CPENC(3,4,C5,C0,1), 0 },
3850 { "teehbr32_el1", CPENC(2,2,C1,C0,0), 0 },
3851 { "sder32_el3", CPENC(3,6,C1,C1,1), 0 },
3852 { "mdscr_el1", CPENC(2,0,C0, C2, 2), 0 },
3853 { "mdccsr_el0", CPENC(2,3,C0, C1, 0), 0 }, /* r */
3854 { "mdccint_el1", CPENC(2,0,C0, C2, 0), 0 },
3855 { "dbgdtr_el0", CPENC(2,3,C0, C4, 0), 0 },
3856 { "dbgdtrrx_el0", CPENC(2,3,C0, C5, 0), 0 }, /* r */
3857 { "dbgdtrtx_el0", CPENC(2,3,C0, C5, 0), 0 }, /* w */
3858 { "osdtrrx_el1", CPENC(2,0,C0, C0, 2), 0 }, /* r */
3859 { "osdtrtx_el1", CPENC(2,0,C0, C3, 2), 0 }, /* w */
3860 { "oseccr_el1", CPENC(2,0,C0, C6, 2), 0 },
3861 { "dbgvcr32_el2", CPENC(2,4,C0, C7, 0), 0 },
3862 { "dbgbvr0_el1", CPENC(2,0,C0, C0, 4), 0 },
3863 { "dbgbvr1_el1", CPENC(2,0,C0, C1, 4), 0 },
3864 { "dbgbvr2_el1", CPENC(2,0,C0, C2, 4), 0 },
3865 { "dbgbvr3_el1", CPENC(2,0,C0, C3, 4), 0 },
3866 { "dbgbvr4_el1", CPENC(2,0,C0, C4, 4), 0 },
3867 { "dbgbvr5_el1", CPENC(2,0,C0, C5, 4), 0 },
3868 { "dbgbvr6_el1", CPENC(2,0,C0, C6, 4), 0 },
3869 { "dbgbvr7_el1", CPENC(2,0,C0, C7, 4), 0 },
3870 { "dbgbvr8_el1", CPENC(2,0,C0, C8, 4), 0 },
3871 { "dbgbvr9_el1", CPENC(2,0,C0, C9, 4), 0 },
3872 { "dbgbvr10_el1", CPENC(2,0,C0, C10,4), 0 },
3873 { "dbgbvr11_el1", CPENC(2,0,C0, C11,4), 0 },
3874 { "dbgbvr12_el1", CPENC(2,0,C0, C12,4), 0 },
3875 { "dbgbvr13_el1", CPENC(2,0,C0, C13,4), 0 },
3876 { "dbgbvr14_el1", CPENC(2,0,C0, C14,4), 0 },
3877 { "dbgbvr15_el1", CPENC(2,0,C0, C15,4), 0 },
3878 { "dbgbcr0_el1", CPENC(2,0,C0, C0, 5), 0 },
3879 { "dbgbcr1_el1", CPENC(2,0,C0, C1, 5), 0 },
3880 { "dbgbcr2_el1", CPENC(2,0,C0, C2, 5), 0 },
3881 { "dbgbcr3_el1", CPENC(2,0,C0, C3, 5), 0 },
3882 { "dbgbcr4_el1", CPENC(2,0,C0, C4, 5), 0 },
3883 { "dbgbcr5_el1", CPENC(2,0,C0, C5, 5), 0 },
3884 { "dbgbcr6_el1", CPENC(2,0,C0, C6, 5), 0 },
3885 { "dbgbcr7_el1", CPENC(2,0,C0, C7, 5), 0 },
3886 { "dbgbcr8_el1", CPENC(2,0,C0, C8, 5), 0 },
3887 { "dbgbcr9_el1", CPENC(2,0,C0, C9, 5), 0 },
3888 { "dbgbcr10_el1", CPENC(2,0,C0, C10,5), 0 },
3889 { "dbgbcr11_el1", CPENC(2,0,C0, C11,5), 0 },
3890 { "dbgbcr12_el1", CPENC(2,0,C0, C12,5), 0 },
3891 { "dbgbcr13_el1", CPENC(2,0,C0, C13,5), 0 },
3892 { "dbgbcr14_el1", CPENC(2,0,C0, C14,5), 0 },
3893 { "dbgbcr15_el1", CPENC(2,0,C0, C15,5), 0 },
3894 { "dbgwvr0_el1", CPENC(2,0,C0, C0, 6), 0 },
3895 { "dbgwvr1_el1", CPENC(2,0,C0, C1, 6), 0 },
3896 { "dbgwvr2_el1", CPENC(2,0,C0, C2, 6), 0 },
3897 { "dbgwvr3_el1", CPENC(2,0,C0, C3, 6), 0 },
3898 { "dbgwvr4_el1", CPENC(2,0,C0, C4, 6), 0 },
3899 { "dbgwvr5_el1", CPENC(2,0,C0, C5, 6), 0 },
3900 { "dbgwvr6_el1", CPENC(2,0,C0, C6, 6), 0 },
3901 { "dbgwvr7_el1", CPENC(2,0,C0, C7, 6), 0 },
3902 { "dbgwvr8_el1", CPENC(2,0,C0, C8, 6), 0 },
3903 { "dbgwvr9_el1", CPENC(2,0,C0, C9, 6), 0 },
3904 { "dbgwvr10_el1", CPENC(2,0,C0, C10,6), 0 },
3905 { "dbgwvr11_el1", CPENC(2,0,C0, C11,6), 0 },
3906 { "dbgwvr12_el1", CPENC(2,0,C0, C12,6), 0 },
3907 { "dbgwvr13_el1", CPENC(2,0,C0, C13,6), 0 },
3908 { "dbgwvr14_el1", CPENC(2,0,C0, C14,6), 0 },
3909 { "dbgwvr15_el1", CPENC(2,0,C0, C15,6), 0 },
3910 { "dbgwcr0_el1", CPENC(2,0,C0, C0, 7), 0 },
3911 { "dbgwcr1_el1", CPENC(2,0,C0, C1, 7), 0 },
3912 { "dbgwcr2_el1", CPENC(2,0,C0, C2, 7), 0 },
3913 { "dbgwcr3_el1", CPENC(2,0,C0, C3, 7), 0 },
3914 { "dbgwcr4_el1", CPENC(2,0,C0, C4, 7), 0 },
3915 { "dbgwcr5_el1", CPENC(2,0,C0, C5, 7), 0 },
3916 { "dbgwcr6_el1", CPENC(2,0,C0, C6, 7), 0 },
3917 { "dbgwcr7_el1", CPENC(2,0,C0, C7, 7), 0 },
3918 { "dbgwcr8_el1", CPENC(2,0,C0, C8, 7), 0 },
3919 { "dbgwcr9_el1", CPENC(2,0,C0, C9, 7), 0 },
3920 { "dbgwcr10_el1", CPENC(2,0,C0, C10,7), 0 },
3921 { "dbgwcr11_el1", CPENC(2,0,C0, C11,7), 0 },
3922 { "dbgwcr12_el1", CPENC(2,0,C0, C12,7), 0 },
3923 { "dbgwcr13_el1", CPENC(2,0,C0, C13,7), 0 },
3924 { "dbgwcr14_el1", CPENC(2,0,C0, C14,7), 0 },
3925 { "dbgwcr15_el1", CPENC(2,0,C0, C15,7), 0 },
3926 { "mdrar_el1", CPENC(2,0,C1, C0, 0), 0 }, /* r */
3927 { "oslar_el1", CPENC(2,0,C1, C0, 4), 0 }, /* w */
3928 { "oslsr_el1", CPENC(2,0,C1, C1, 4), 0 }, /* r */
3929 { "osdlr_el1", CPENC(2,0,C1, C3, 4), 0 },
3930 { "dbgprcr_el1", CPENC(2,0,C1, C4, 4), 0 },
3931 { "dbgclaimset_el1", CPENC(2,0,C7, C8, 6), 0 },
3932 { "dbgclaimclr_el1", CPENC(2,0,C7, C9, 6), 0 },
3933 { "dbgauthstatus_el1", CPENC(2,0,C7, C14,6), 0 }, /* r */
3934 { "pmblimitr_el1", CPENC (3, 0, C9, C10, 0), F_ARCHEXT }, /* rw */
3935 { "pmbptr_el1", CPENC (3, 0, C9, C10, 1), F_ARCHEXT }, /* rw */
3936 { "pmbsr_el1", CPENC (3, 0, C9, C10, 3), F_ARCHEXT }, /* rw */
3937 { "pmbidr_el1", CPENC (3, 0, C9, C10, 7), F_ARCHEXT }, /* ro */
3938 { "pmscr_el1", CPENC (3, 0, C9, C9, 0), F_ARCHEXT }, /* rw */
3939 { "pmsicr_el1", CPENC (3, 0, C9, C9, 2), F_ARCHEXT }, /* rw */
3940 { "pmsirr_el1", CPENC (3, 0, C9, C9, 3), F_ARCHEXT }, /* rw */
3941 { "pmsfcr_el1", CPENC (3, 0, C9, C9, 4), F_ARCHEXT }, /* rw */
3942 { "pmsevfr_el1", CPENC (3, 0, C9, C9, 5), F_ARCHEXT }, /* rw */
3943 { "pmslatfr_el1", CPENC (3, 0, C9, C9, 6), F_ARCHEXT }, /* rw */
3944 { "pmsidr_el1", CPENC (3, 0, C9, C9, 7), F_ARCHEXT }, /* ro */
3945 { "pmscr_el2", CPENC (3, 4, C9, C9, 0), F_ARCHEXT }, /* rw */
3946 { "pmscr_el12", CPENC (3, 5, C9, C9, 0), F_ARCHEXT }, /* rw */
3947 { "pmcr_el0", CPENC(3,3,C9,C12, 0), 0 },
3948 { "pmcntenset_el0", CPENC(3,3,C9,C12, 1), 0 },
3949 { "pmcntenclr_el0", CPENC(3,3,C9,C12, 2), 0 },
3950 { "pmovsclr_el0", CPENC(3,3,C9,C12, 3), 0 },
3951 { "pmswinc_el0", CPENC(3,3,C9,C12, 4), 0 }, /* w */
3952 { "pmselr_el0", CPENC(3,3,C9,C12, 5), 0 },
3953 { "pmceid0_el0", CPENC(3,3,C9,C12, 6), 0 }, /* r */
3954 { "pmceid1_el0", CPENC(3,3,C9,C12, 7), 0 }, /* r */
3955 { "pmccntr_el0", CPENC(3,3,C9,C13, 0), 0 },
3956 { "pmxevtyper_el0", CPENC(3,3,C9,C13, 1), 0 },
3957 { "pmxevcntr_el0", CPENC(3,3,C9,C13, 2), 0 },
3958 { "pmuserenr_el0", CPENC(3,3,C9,C14, 0), 0 },
3959 { "pmintenset_el1", CPENC(3,0,C9,C14, 1), 0 },
3960 { "pmintenclr_el1", CPENC(3,0,C9,C14, 2), 0 },
3961 { "pmovsset_el0", CPENC(3,3,C9,C14, 3), 0 },
3962 { "pmevcntr0_el0", CPENC(3,3,C14,C8, 0), 0 },
3963 { "pmevcntr1_el0", CPENC(3,3,C14,C8, 1), 0 },
3964 { "pmevcntr2_el0", CPENC(3,3,C14,C8, 2), 0 },
3965 { "pmevcntr3_el0", CPENC(3,3,C14,C8, 3), 0 },
3966 { "pmevcntr4_el0", CPENC(3,3,C14,C8, 4), 0 },
3967 { "pmevcntr5_el0", CPENC(3,3,C14,C8, 5), 0 },
3968 { "pmevcntr6_el0", CPENC(3,3,C14,C8, 6), 0 },
3969 { "pmevcntr7_el0", CPENC(3,3,C14,C8, 7), 0 },
3970 { "pmevcntr8_el0", CPENC(3,3,C14,C9, 0), 0 },
3971 { "pmevcntr9_el0", CPENC(3,3,C14,C9, 1), 0 },
3972 { "pmevcntr10_el0", CPENC(3,3,C14,C9, 2), 0 },
3973 { "pmevcntr11_el0", CPENC(3,3,C14,C9, 3), 0 },
3974 { "pmevcntr12_el0", CPENC(3,3,C14,C9, 4), 0 },
3975 { "pmevcntr13_el0", CPENC(3,3,C14,C9, 5), 0 },
3976 { "pmevcntr14_el0", CPENC(3,3,C14,C9, 6), 0 },
3977 { "pmevcntr15_el0", CPENC(3,3,C14,C9, 7), 0 },
3978 { "pmevcntr16_el0", CPENC(3,3,C14,C10,0), 0 },
3979 { "pmevcntr17_el0", CPENC(3,3,C14,C10,1), 0 },
3980 { "pmevcntr18_el0", CPENC(3,3,C14,C10,2), 0 },
3981 { "pmevcntr19_el0", CPENC(3,3,C14,C10,3), 0 },
3982 { "pmevcntr20_el0", CPENC(3,3,C14,C10,4), 0 },
3983 { "pmevcntr21_el0", CPENC(3,3,C14,C10,5), 0 },
3984 { "pmevcntr22_el0", CPENC(3,3,C14,C10,6), 0 },
3985 { "pmevcntr23_el0", CPENC(3,3,C14,C10,7), 0 },
3986 { "pmevcntr24_el0", CPENC(3,3,C14,C11,0), 0 },
3987 { "pmevcntr25_el0", CPENC(3,3,C14,C11,1), 0 },
3988 { "pmevcntr26_el0", CPENC(3,3,C14,C11,2), 0 },
3989 { "pmevcntr27_el0", CPENC(3,3,C14,C11,3), 0 },
3990 { "pmevcntr28_el0", CPENC(3,3,C14,C11,4), 0 },
3991 { "pmevcntr29_el0", CPENC(3,3,C14,C11,5), 0 },
3992 { "pmevcntr30_el0", CPENC(3,3,C14,C11,6), 0 },
3993 { "pmevtyper0_el0", CPENC(3,3,C14,C12,0), 0 },
3994 { "pmevtyper1_el0", CPENC(3,3,C14,C12,1), 0 },
3995 { "pmevtyper2_el0", CPENC(3,3,C14,C12,2), 0 },
3996 { "pmevtyper3_el0", CPENC(3,3,C14,C12,3), 0 },
3997 { "pmevtyper4_el0", CPENC(3,3,C14,C12,4), 0 },
3998 { "pmevtyper5_el0", CPENC(3,3,C14,C12,5), 0 },
3999 { "pmevtyper6_el0", CPENC(3,3,C14,C12,6), 0 },
4000 { "pmevtyper7_el0", CPENC(3,3,C14,C12,7), 0 },
4001 { "pmevtyper8_el0", CPENC(3,3,C14,C13,0), 0 },
4002 { "pmevtyper9_el0", CPENC(3,3,C14,C13,1), 0 },
4003 { "pmevtyper10_el0", CPENC(3,3,C14,C13,2), 0 },
4004 { "pmevtyper11_el0", CPENC(3,3,C14,C13,3), 0 },
4005 { "pmevtyper12_el0", CPENC(3,3,C14,C13,4), 0 },
4006 { "pmevtyper13_el0", CPENC(3,3,C14,C13,5), 0 },
4007 { "pmevtyper14_el0", CPENC(3,3,C14,C13,6), 0 },
4008 { "pmevtyper15_el0", CPENC(3,3,C14,C13,7), 0 },
4009 { "pmevtyper16_el0", CPENC(3,3,C14,C14,0), 0 },
4010 { "pmevtyper17_el0", CPENC(3,3,C14,C14,1), 0 },
4011 { "pmevtyper18_el0", CPENC(3,3,C14,C14,2), 0 },
4012 { "pmevtyper19_el0", CPENC(3,3,C14,C14,3), 0 },
4013 { "pmevtyper20_el0", CPENC(3,3,C14,C14,4), 0 },
4014 { "pmevtyper21_el0", CPENC(3,3,C14,C14,5), 0 },
4015 { "pmevtyper22_el0", CPENC(3,3,C14,C14,6), 0 },
4016 { "pmevtyper23_el0", CPENC(3,3,C14,C14,7), 0 },
4017 { "pmevtyper24_el0", CPENC(3,3,C14,C15,0), 0 },
4018 { "pmevtyper25_el0", CPENC(3,3,C14,C15,1), 0 },
4019 { "pmevtyper26_el0", CPENC(3,3,C14,C15,2), 0 },
4020 { "pmevtyper27_el0", CPENC(3,3,C14,C15,3), 0 },
4021 { "pmevtyper28_el0", CPENC(3,3,C14,C15,4), 0 },
4022 { "pmevtyper29_el0", CPENC(3,3,C14,C15,5), 0 },
4023 { "pmevtyper30_el0", CPENC(3,3,C14,C15,6), 0 },
4024 { "pmccfiltr_el0", CPENC(3,3,C14,C15,7), 0 },
4025 { 0, CPENC(0,0,0,0,0), 0 },
4029 aarch64_sys_reg_deprecated_p (const aarch64_sys_reg *reg)
4031 return (reg->flags & F_DEPRECATED) != 0;
4035 aarch64_sys_reg_supported_p (const aarch64_feature_set features,
4036 const aarch64_sys_reg *reg)
4038 if (!(reg->flags & F_ARCHEXT))
4041 /* PAN. Values are from aarch64_sys_regs. */
4042 if (reg->value == CPEN_(0,C2,3)
4043 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_PAN))
4046 /* Virtualization host extensions: system registers. */
4047 if ((reg->value == CPENC (3, 4, C2, C0, 1)
4048 || reg->value == CPENC (3, 4, C13, C0, 1)
4049 || reg->value == CPENC (3, 4, C14, C3, 0)
4050 || reg->value == CPENC (3, 4, C14, C3, 1)
4051 || reg->value == CPENC (3, 4, C14, C3, 2))
4052 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_1))
4055 /* Virtualization host extensions: *_el12 names of *_el1 registers. */
4056 if ((reg->value == CPEN_ (5, C0, 0)
4057 || reg->value == CPEN_ (5, C0, 1)
4058 || reg->value == CPENC (3, 5, C1, C0, 0)
4059 || reg->value == CPENC (3, 5, C1, C0, 2)
4060 || reg->value == CPENC (3, 5, C2, C0, 0)
4061 || reg->value == CPENC (3, 5, C2, C0, 1)
4062 || reg->value == CPENC (3, 5, C2, C0, 2)
4063 || reg->value == CPENC (3, 5, C5, C1, 0)
4064 || reg->value == CPENC (3, 5, C5, C1, 1)
4065 || reg->value == CPENC (3, 5, C5, C2, 0)
4066 || reg->value == CPENC (3, 5, C6, C0, 0)
4067 || reg->value == CPENC (3, 5, C10, C2, 0)
4068 || reg->value == CPENC (3, 5, C10, C3, 0)
4069 || reg->value == CPENC (3, 5, C12, C0, 0)
4070 || reg->value == CPENC (3, 5, C13, C0, 1)
4071 || reg->value == CPENC (3, 5, C14, C1, 0))
4072 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_1))
4075 /* Virtualization host extensions: *_el02 names of *_el0 registers. */
4076 if ((reg->value == CPENC (3, 5, C14, C2, 0)
4077 || reg->value == CPENC (3, 5, C14, C2, 1)
4078 || reg->value == CPENC (3, 5, C14, C2, 2)
4079 || reg->value == CPENC (3, 5, C14, C3, 0)
4080 || reg->value == CPENC (3, 5, C14, C3, 1)
4081 || reg->value == CPENC (3, 5, C14, C3, 2))
4082 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_1))
4085 /* ARMv8.2 features. */
4087 /* ID_AA64MMFR2_EL1. */
4088 if (reg->value == CPENC (3, 0, C0, C7, 2)
4089 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
4093 if (reg->value == CPEN_ (0, C2, 4)
4094 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
4097 /* RAS extension. */
4099 /* ERRIDR_EL1, ERRSELR_EL1, ERXFR_EL1, ERXCTLR_EL1, ERXSTATUS_EL, ERXADDR_EL1,
4100 ERXMISC0_EL1 AND ERXMISC1_EL1. */
4101 if ((reg->value == CPENC (3, 0, C5, C3, 0)
4102 || reg->value == CPENC (3, 0, C5, C3, 1)
4103 || reg->value == CPENC (3, 0, C5, C3, 2)
4104 || reg->value == CPENC (3, 0, C5, C3, 3)
4105 || reg->value == CPENC (3, 0, C5, C4, 0)
4106 || reg->value == CPENC (3, 0, C5, C4, 1)
4107 || reg->value == CPENC (3, 0, C5, C4, 2)
4108 || reg->value == CPENC (3, 0, C5, C4, 3)
4109 || reg->value == CPENC (3, 0, C5, C5, 0)
4110 || reg->value == CPENC (3, 0, C5, C5, 1))
4111 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_RAS))
4114 /* VSESR_EL2, DISR_EL1 and VDISR_EL2. */
4115 if ((reg->value == CPENC (3, 4, C5, C2, 3)
4116 || reg->value == CPENC (3, 0, C12, C1, 1)
4117 || reg->value == CPENC (3, 4, C12, C1, 1))
4118 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_RAS))
4121 /* Statistical Profiling extension. */
4122 if ((reg->value == CPENC (3, 0, C9, C10, 0)
4123 || reg->value == CPENC (3, 0, C9, C10, 1)
4124 || reg->value == CPENC (3, 0, C9, C10, 3)
4125 || reg->value == CPENC (3, 0, C9, C10, 7)
4126 || reg->value == CPENC (3, 0, C9, C9, 0)
4127 || reg->value == CPENC (3, 0, C9, C9, 2)
4128 || reg->value == CPENC (3, 0, C9, C9, 3)
4129 || reg->value == CPENC (3, 0, C9, C9, 4)
4130 || reg->value == CPENC (3, 0, C9, C9, 5)
4131 || reg->value == CPENC (3, 0, C9, C9, 6)
4132 || reg->value == CPENC (3, 0, C9, C9, 7)
4133 || reg->value == CPENC (3, 4, C9, C9, 0)
4134 || reg->value == CPENC (3, 5, C9, C9, 0))
4135 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_PROFILE))
4138 /* ARMv8.3 Pointer authentication keys. */
4139 if ((reg->value == CPENC (3, 0, C2, C1, 0)
4140 || reg->value == CPENC (3, 0, C2, C1, 1)
4141 || reg->value == CPENC (3, 0, C2, C1, 2)
4142 || reg->value == CPENC (3, 0, C2, C1, 3)
4143 || reg->value == CPENC (3, 0, C2, C2, 0)
4144 || reg->value == CPENC (3, 0, C2, C2, 1)
4145 || reg->value == CPENC (3, 0, C2, C2, 2)
4146 || reg->value == CPENC (3, 0, C2, C2, 3)
4147 || reg->value == CPENC (3, 0, C2, C3, 0)
4148 || reg->value == CPENC (3, 0, C2, C3, 1))
4149 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_3))
4153 if ((reg->value == CPENC (3, 0, C0, C4, 4)
4154 || reg->value == CPENC (3, 0, C1, C2, 0)
4155 || reg->value == CPENC (3, 4, C1, C2, 0)
4156 || reg->value == CPENC (3, 6, C1, C2, 0)
4157 || reg->value == CPENC (3, 5, C1, C2, 0)
4158 || reg->value == CPENC (3, 0, C0, C0, 7))
4159 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_SVE))
4165 const aarch64_sys_reg aarch64_pstatefields [] =
4167 { "spsel", 0x05, 0 },
4168 { "daifset", 0x1e, 0 },
4169 { "daifclr", 0x1f, 0 },
4170 { "pan", 0x04, F_ARCHEXT },
4171 { "uao", 0x03, F_ARCHEXT },
4172 { 0, CPENC(0,0,0,0,0), 0 },
4176 aarch64_pstatefield_supported_p (const aarch64_feature_set features,
4177 const aarch64_sys_reg *reg)
4179 if (!(reg->flags & F_ARCHEXT))
4182 /* PAN. Values are from aarch64_pstatefields. */
4183 if (reg->value == 0x04
4184 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_PAN))
4187 /* UAO. Values are from aarch64_pstatefields. */
4188 if (reg->value == 0x03
4189 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
4195 const aarch64_sys_ins_reg aarch64_sys_regs_ic[] =
4197 { "ialluis", CPENS(0,C7,C1,0), 0 },
4198 { "iallu", CPENS(0,C7,C5,0), 0 },
4199 { "ivau", CPENS (3, C7, C5, 1), F_HASXT },
4200 { 0, CPENS(0,0,0,0), 0 }
4203 const aarch64_sys_ins_reg aarch64_sys_regs_dc[] =
4205 { "zva", CPENS (3, C7, C4, 1), F_HASXT },
4206 { "ivac", CPENS (0, C7, C6, 1), F_HASXT },
4207 { "isw", CPENS (0, C7, C6, 2), F_HASXT },
4208 { "cvac", CPENS (3, C7, C10, 1), F_HASXT },
4209 { "csw", CPENS (0, C7, C10, 2), F_HASXT },
4210 { "cvau", CPENS (3, C7, C11, 1), F_HASXT },
4211 { "cvap", CPENS (3, C7, C12, 1), F_HASXT | F_ARCHEXT },
4212 { "civac", CPENS (3, C7, C14, 1), F_HASXT },
4213 { "cisw", CPENS (0, C7, C14, 2), F_HASXT },
4214 { 0, CPENS(0,0,0,0), 0 }
4217 const aarch64_sys_ins_reg aarch64_sys_regs_at[] =
4219 { "s1e1r", CPENS (0, C7, C8, 0), F_HASXT },
4220 { "s1e1w", CPENS (0, C7, C8, 1), F_HASXT },
4221 { "s1e0r", CPENS (0, C7, C8, 2), F_HASXT },
4222 { "s1e0w", CPENS (0, C7, C8, 3), F_HASXT },
4223 { "s12e1r", CPENS (4, C7, C8, 4), F_HASXT },
4224 { "s12e1w", CPENS (4, C7, C8, 5), F_HASXT },
4225 { "s12e0r", CPENS (4, C7, C8, 6), F_HASXT },
4226 { "s12e0w", CPENS (4, C7, C8, 7), F_HASXT },
4227 { "s1e2r", CPENS (4, C7, C8, 0), F_HASXT },
4228 { "s1e2w", CPENS (4, C7, C8, 1), F_HASXT },
4229 { "s1e3r", CPENS (6, C7, C8, 0), F_HASXT },
4230 { "s1e3w", CPENS (6, C7, C8, 1), F_HASXT },
4231 { "s1e1rp", CPENS (0, C7, C9, 0), F_HASXT | F_ARCHEXT },
4232 { "s1e1wp", CPENS (0, C7, C9, 1), F_HASXT | F_ARCHEXT },
4233 { 0, CPENS(0,0,0,0), 0 }
4236 const aarch64_sys_ins_reg aarch64_sys_regs_tlbi[] =
4238 { "vmalle1", CPENS(0,C8,C7,0), 0 },
4239 { "vae1", CPENS (0, C8, C7, 1), F_HASXT },
4240 { "aside1", CPENS (0, C8, C7, 2), F_HASXT },
4241 { "vaae1", CPENS (0, C8, C7, 3), F_HASXT },
4242 { "vmalle1is", CPENS(0,C8,C3,0), 0 },
4243 { "vae1is", CPENS (0, C8, C3, 1), F_HASXT },
4244 { "aside1is", CPENS (0, C8, C3, 2), F_HASXT },
4245 { "vaae1is", CPENS (0, C8, C3, 3), F_HASXT },
4246 { "ipas2e1is", CPENS (4, C8, C0, 1), F_HASXT },
4247 { "ipas2le1is",CPENS (4, C8, C0, 5), F_HASXT },
4248 { "ipas2e1", CPENS (4, C8, C4, 1), F_HASXT },
4249 { "ipas2le1", CPENS (4, C8, C4, 5), F_HASXT },
4250 { "vae2", CPENS (4, C8, C7, 1), F_HASXT },
4251 { "vae2is", CPENS (4, C8, C3, 1), F_HASXT },
4252 { "vmalls12e1",CPENS(4,C8,C7,6), 0 },
4253 { "vmalls12e1is",CPENS(4,C8,C3,6), 0 },
4254 { "vae3", CPENS (6, C8, C7, 1), F_HASXT },
4255 { "vae3is", CPENS (6, C8, C3, 1), F_HASXT },
4256 { "alle2", CPENS(4,C8,C7,0), 0 },
4257 { "alle2is", CPENS(4,C8,C3,0), 0 },
4258 { "alle1", CPENS(4,C8,C7,4), 0 },
4259 { "alle1is", CPENS(4,C8,C3,4), 0 },
4260 { "alle3", CPENS(6,C8,C7,0), 0 },
4261 { "alle3is", CPENS(6,C8,C3,0), 0 },
4262 { "vale1is", CPENS (0, C8, C3, 5), F_HASXT },
4263 { "vale2is", CPENS (4, C8, C3, 5), F_HASXT },
4264 { "vale3is", CPENS (6, C8, C3, 5), F_HASXT },
4265 { "vaale1is", CPENS (0, C8, C3, 7), F_HASXT },
4266 { "vale1", CPENS (0, C8, C7, 5), F_HASXT },
4267 { "vale2", CPENS (4, C8, C7, 5), F_HASXT },
4268 { "vale3", CPENS (6, C8, C7, 5), F_HASXT },
4269 { "vaale1", CPENS (0, C8, C7, 7), F_HASXT },
4270 { 0, CPENS(0,0,0,0), 0 }
4274 aarch64_sys_ins_reg_has_xt (const aarch64_sys_ins_reg *sys_ins_reg)
4276 return (sys_ins_reg->flags & F_HASXT) != 0;
4280 aarch64_sys_ins_reg_supported_p (const aarch64_feature_set features,
4281 const aarch64_sys_ins_reg *reg)
4283 if (!(reg->flags & F_ARCHEXT))
4286 /* DC CVAP. Values are from aarch64_sys_regs_dc. */
4287 if (reg->value == CPENS (3, C7, C12, 1)
4288 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
4291 /* AT S1E1RP, AT S1E1WP. Values are from aarch64_sys_regs_at. */
4292 if ((reg->value == CPENS (0, C7, C9, 0)
4293 || reg->value == CPENS (0, C7, C9, 1))
4294 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
4317 #define BIT(INSN,BT) (((INSN) >> (BT)) & 1)
4318 #define BITS(INSN,HI,LO) (((INSN) >> (LO)) & ((1 << (((HI) - (LO)) + 1)) - 1))
4321 verify_ldpsw (const struct aarch64_opcode * opcode ATTRIBUTE_UNUSED,
4322 const aarch64_insn insn)
4324 int t = BITS (insn, 4, 0);
4325 int n = BITS (insn, 9, 5);
4326 int t2 = BITS (insn, 14, 10);
4330 /* Write back enabled. */
4331 if ((t == n || t2 == n) && n != 31)
4345 /* Return true if VALUE cannot be moved into an SVE register using DUP
4346 (with any element size, not just ESIZE) and if using DUPM would
4347 therefore be OK. ESIZE is the number of bytes in the immediate. */
4350 aarch64_sve_dupm_mov_immediate_p (uint64_t uvalue, int esize)
4352 int64_t svalue = uvalue;
4353 uint64_t upper = (uint64_t) -1 << (esize * 4) << (esize * 4);
4355 if ((uvalue & ~upper) != uvalue && (uvalue | upper) != uvalue)
4357 if (esize <= 4 || (uint32_t) uvalue == (uint32_t) (uvalue >> 32))
4359 svalue = (int32_t) uvalue;
4360 if (esize <= 2 || (uint16_t) uvalue == (uint16_t) (uvalue >> 16))
4362 svalue = (int16_t) uvalue;
4363 if (esize == 1 || (uint8_t) uvalue == (uint8_t) (uvalue >> 8))
4367 if ((svalue & 0xff) == 0)
4369 return svalue < -128 || svalue >= 128;
4372 /* Include the opcode description table as well as the operand description
4374 #define VERIFIER(x) verify_##x
4375 #include "aarch64-tbl.h"