[AArch64] Add ARMv8.3 PACGA instruction
[deliverable/binutils-gdb.git] / opcodes / aarch64-opc.c
CommitLineData
a06ea964 1/* aarch64-opc.c -- AArch64 opcode support.
6f2750fe 2 Copyright (C) 2009-2016 Free Software Foundation, Inc.
a06ea964
NC
3 Contributed by ARM Ltd.
4
5 This file is part of the GNU opcodes library.
6
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)
10 any later version.
11
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.
16
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/>. */
20
21#include "sysdep.h"
22#include <assert.h>
23#include <stdlib.h>
24#include <stdio.h>
25#include <stdint.h>
26#include <stdarg.h>
27#include <inttypes.h>
28
29#include "opintl.h"
245d2e3f 30#include "libiberty.h"
a06ea964
NC
31
32#include "aarch64-opc.h"
33
34#ifdef DEBUG_AARCH64
35int debug_dump = FALSE;
36#endif /* DEBUG_AARCH64 */
37
245d2e3f
RS
38/* The enumeration strings associated with each value of a 5-bit SVE
39 pattern operand. A null entry indicates a reserved meaning. */
40const char *const aarch64_sve_pattern_array[32] = {
41 /* 0-7. */
42 "pow2",
43 "vl1",
44 "vl2",
45 "vl3",
46 "vl4",
47 "vl5",
48 "vl6",
49 "vl7",
50 /* 8-15. */
51 "vl8",
52 "vl16",
53 "vl32",
54 "vl64",
55 "vl128",
56 "vl256",
57 0,
58 0,
59 /* 16-23. */
60 0,
61 0,
62 0,
63 0,
64 0,
65 0,
66 0,
67 0,
68 /* 24-31. */
69 0,
70 0,
71 0,
72 0,
73 0,
74 "mul4",
75 "mul3",
76 "all"
77};
78
79/* The enumeration strings associated with each value of a 4-bit SVE
80 prefetch operand. A null entry indicates a reserved meaning. */
81const char *const aarch64_sve_prfop_array[16] = {
82 /* 0-7. */
83 "pldl1keep",
84 "pldl1strm",
85 "pldl2keep",
86 "pldl2strm",
87 "pldl3keep",
88 "pldl3strm",
89 0,
90 0,
91 /* 8-15. */
92 "pstl1keep",
93 "pstl1strm",
94 "pstl2keep",
95 "pstl2strm",
96 "pstl3keep",
97 "pstl3strm",
98 0,
99 0
100};
101
a06ea964
NC
102/* Helper functions to determine which operand to be used to encode/decode
103 the size:Q fields for AdvSIMD instructions. */
104
105static inline bfd_boolean
106vector_qualifier_p (enum aarch64_opnd_qualifier qualifier)
107{
108 return ((qualifier >= AARCH64_OPND_QLF_V_8B
109 && qualifier <= AARCH64_OPND_QLF_V_1Q) ? TRUE
110 : FALSE);
111}
112
113static inline bfd_boolean
114fp_qualifier_p (enum aarch64_opnd_qualifier qualifier)
115{
116 return ((qualifier >= AARCH64_OPND_QLF_S_B
117 && qualifier <= AARCH64_OPND_QLF_S_Q) ? TRUE
118 : FALSE);
119}
120
121enum data_pattern
122{
123 DP_UNKNOWN,
124 DP_VECTOR_3SAME,
125 DP_VECTOR_LONG,
126 DP_VECTOR_WIDE,
127 DP_VECTOR_ACROSS_LANES,
128};
129
130static const char significant_operand_index [] =
131{
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 */
137};
138
139/* Given a sequence of qualifiers in QUALIFIERS, determine and return
140 the data pattern.
141 N.B. QUALIFIERS is a possible sequence of qualifiers each of which
142 corresponds to one of a sequence of operands. */
143
144static enum data_pattern
145get_data_pattern (const aarch64_opnd_qualifier_seq_t qualifiers)
146{
147 if (vector_qualifier_p (qualifiers[0]) == TRUE)
148 {
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].
160 or v.8h, v.16b. */
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;
175 }
176 else if (fp_qualifier_p (qualifiers[0]) == TRUE)
177 {
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;
182 }
183
184 return DP_UNKNOWN;
185}
186
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
193 benefit. */
194
195int
196aarch64_select_operand_for_sizeq_field_coding (const aarch64_opcode *opcode)
197{
198 return
199 significant_operand_index [get_data_pattern (opcode->qualifiers_list[0])];
200}
201\f
202const aarch64_field fields[] =
203{
204 { 0, 0 }, /* NIL. */
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 }, /* N: in logical (immediate) instructions. */
257 { 11, 1 }, /* index: in ld/st inst deciding the pre/post-index. */
258 { 24, 1 }, /* index2: in ld/st pair inst deciding the pre/post-index. */
259 { 31, 1 }, /* sf: in integer data processing instructions. */
ee804238 260 { 30, 1 }, /* lse_size: in LSE extension atomic instructions. */
a06ea964
NC
261 { 11, 1 }, /* H: in advsimd scalar x indexed element instructions. */
262 { 21, 1 }, /* L: in advsimd scalar x indexed element instructions. */
263 { 20, 1 }, /* M: in advsimd scalar x indexed element instructions. */
264 { 31, 1 }, /* b5: in the test bit and branch instructions. */
265 { 19, 5 }, /* b40: in the test bit and branch instructions. */
266 { 10, 6 }, /* scale: in the fixed-point scalar to fp converting inst. */
116b6019
RS
267 { 4, 1 }, /* SVE_M_4: Merge/zero select, bit 4. */
268 { 14, 1 }, /* SVE_M_14: Merge/zero select, bit 14. */
269 { 16, 1 }, /* SVE_M_16: Merge/zero select, bit 16. */
e950b345 270 { 17, 1 }, /* SVE_N: SVE equivalent of N. */
f11ad6bc
RS
271 { 0, 4 }, /* SVE_Pd: p0-p15, bits [3,0]. */
272 { 10, 3 }, /* SVE_Pg3: p0-p7, bits [12,10]. */
273 { 5, 4 }, /* SVE_Pg4_5: p0-p15, bits [8,5]. */
274 { 10, 4 }, /* SVE_Pg4_10: p0-p15, bits [13,10]. */
275 { 16, 4 }, /* SVE_Pg4_16: p0-p15, bits [19,16]. */
276 { 16, 4 }, /* SVE_Pm: p0-p15, bits [19,16]. */
277 { 5, 4 }, /* SVE_Pn: p0-p15, bits [8,5]. */
278 { 0, 4 }, /* SVE_Pt: p0-p15, bits [3,0]. */
047cd301
RS
279 { 5, 5 }, /* SVE_Rm: SVE alternative position for Rm. */
280 { 16, 5 }, /* SVE_Rn: SVE alternative position for Rn. */
281 { 0, 5 }, /* SVE_Vd: Scalar SIMD&FP register, bits [4,0]. */
282 { 5, 5 }, /* SVE_Vm: Scalar SIMD&FP register, bits [9,5]. */
283 { 5, 5 }, /* SVE_Vn: Scalar SIMD&FP register, bits [9,5]. */
f11ad6bc
RS
284 { 5, 5 }, /* SVE_Za_5: SVE vector register, bits [9,5]. */
285 { 16, 5 }, /* SVE_Za_16: SVE vector register, bits [20,16]. */
286 { 0, 5 }, /* SVE_Zd: SVE vector register. bits [4,0]. */
287 { 5, 5 }, /* SVE_Zm_5: SVE vector register, bits [9,5]. */
288 { 16, 5 }, /* SVE_Zm_16: SVE vector register, bits [20,16]. */
289 { 5, 5 }, /* SVE_Zn: SVE vector register, bits [9,5]. */
290 { 0, 5 }, /* SVE_Zt: SVE vector register, bits [4,0]. */
165d4950 291 { 5, 1 }, /* SVE_i1: single-bit immediate. */
e950b345 292 { 16, 3 }, /* SVE_imm3: 3-bit immediate field. */
2442d846 293 { 16, 4 }, /* SVE_imm4: 4-bit immediate field. */
e950b345
RS
294 { 5, 5 }, /* SVE_imm5: 5-bit immediate field. */
295 { 16, 5 }, /* SVE_imm5b: secondary 5-bit immediate field. */
4df068de 296 { 16, 6 }, /* SVE_imm6: 6-bit immediate field. */
e950b345
RS
297 { 14, 7 }, /* SVE_imm7: 7-bit immediate field. */
298 { 5, 8 }, /* SVE_imm8: 8-bit immediate field. */
299 { 5, 9 }, /* SVE_imm9: 9-bit immediate field. */
300 { 11, 6 }, /* SVE_immr: SVE equivalent of immr. */
301 { 5, 6 }, /* SVE_imms: SVE equivalent of imms. */
4df068de 302 { 10, 2 }, /* SVE_msz: 2-bit shift amount for ADR. */
245d2e3f
RS
303 { 5, 5 }, /* SVE_pattern: vector pattern enumeration. */
304 { 0, 4 }, /* SVE_prfop: prefetch operation for SVE PRF[BHWD]. */
116b6019
RS
305 { 22, 1 }, /* SVE_sz: 1-bit element size select. */
306 { 16, 4 }, /* SVE_tsz: triangular size select. */
f11ad6bc 307 { 22, 2 }, /* SVE_tszh: triangular size select high, bits [23,22]. */
116b6019
RS
308 { 8, 2 }, /* SVE_tszl_8: triangular size select low, bits [9,8]. */
309 { 19, 2 }, /* SVE_tszl_19: triangular size select low, bits [20,19]. */
4df068de
RS
310 { 14, 1 }, /* SVE_xs_14: UXTW/SXTW select (bit 14). */
311 { 22, 1 } /* SVE_xs_22: UXTW/SXTW select (bit 22). */
a06ea964
NC
312};
313
314enum aarch64_operand_class
315aarch64_get_operand_class (enum aarch64_opnd type)
316{
317 return aarch64_operands[type].op_class;
318}
319
320const char *
321aarch64_get_operand_name (enum aarch64_opnd type)
322{
323 return aarch64_operands[type].name;
324}
325
326/* Get operand description string.
327 This is usually for the diagnosis purpose. */
328const char *
329aarch64_get_operand_desc (enum aarch64_opnd type)
330{
331 return aarch64_operands[type].desc;
332}
333
334/* Table of all conditional affixes. */
335const aarch64_cond aarch64_conds[16] =
336{
bb7eff52
RS
337 {{"eq", "none"}, 0x0},
338 {{"ne", "any"}, 0x1},
339 {{"cs", "hs", "nlast"}, 0x2},
340 {{"cc", "lo", "ul", "last"}, 0x3},
341 {{"mi", "first"}, 0x4},
342 {{"pl", "nfrst"}, 0x5},
a06ea964
NC
343 {{"vs"}, 0x6},
344 {{"vc"}, 0x7},
bb7eff52
RS
345 {{"hi", "pmore"}, 0x8},
346 {{"ls", "plast"}, 0x9},
347 {{"ge", "tcont"}, 0xa},
348 {{"lt", "tstop"}, 0xb},
a06ea964
NC
349 {{"gt"}, 0xc},
350 {{"le"}, 0xd},
351 {{"al"}, 0xe},
352 {{"nv"}, 0xf},
353};
354
355const aarch64_cond *
356get_cond_from_value (aarch64_insn value)
357{
358 assert (value < 16);
359 return &aarch64_conds[(unsigned int) value];
360}
361
362const aarch64_cond *
363get_inverted_cond (const aarch64_cond *cond)
364{
365 return &aarch64_conds[cond->value ^ 0x1];
366}
367
368/* Table describing the operand extension/shifting operators; indexed by
369 enum aarch64_modifier_kind.
370
371 The value column provides the most common values for encoding modifiers,
372 which enables table-driven encoding/decoding for the modifiers. */
373const struct aarch64_name_value_pair aarch64_operand_modifiers [] =
374{
375 {"none", 0x0},
376 {"msl", 0x0},
377 {"ror", 0x3},
378 {"asr", 0x2},
379 {"lsr", 0x1},
380 {"lsl", 0x0},
381 {"uxtb", 0x0},
382 {"uxth", 0x1},
383 {"uxtw", 0x2},
384 {"uxtx", 0x3},
385 {"sxtb", 0x4},
386 {"sxth", 0x5},
387 {"sxtw", 0x6},
388 {"sxtx", 0x7},
2442d846 389 {"mul", 0x0},
98907a70 390 {"mul vl", 0x0},
a06ea964
NC
391 {NULL, 0},
392};
393
394enum aarch64_modifier_kind
395aarch64_get_operand_modifier (const struct aarch64_name_value_pair *desc)
396{
397 return desc - aarch64_operand_modifiers;
398}
399
400aarch64_insn
401aarch64_get_operand_modifier_value (enum aarch64_modifier_kind kind)
402{
403 return aarch64_operand_modifiers[kind].value;
404}
405
406enum aarch64_modifier_kind
407aarch64_get_operand_modifier_from_value (aarch64_insn value,
408 bfd_boolean extend_p)
409{
410 if (extend_p == TRUE)
411 return AARCH64_MOD_UXTB + value;
412 else
413 return AARCH64_MOD_LSL - value;
414}
415
416bfd_boolean
417aarch64_extend_operator_p (enum aarch64_modifier_kind kind)
418{
419 return (kind > AARCH64_MOD_LSL && kind <= AARCH64_MOD_SXTX)
420 ? TRUE : FALSE;
421}
422
423static inline bfd_boolean
424aarch64_shift_operator_p (enum aarch64_modifier_kind kind)
425{
426 return (kind >= AARCH64_MOD_ROR && kind <= AARCH64_MOD_LSL)
427 ? TRUE : FALSE;
428}
429
430const struct aarch64_name_value_pair aarch64_barrier_options[16] =
431{
432 { "#0x00", 0x0 },
433 { "oshld", 0x1 },
434 { "oshst", 0x2 },
435 { "osh", 0x3 },
436 { "#0x04", 0x4 },
437 { "nshld", 0x5 },
438 { "nshst", 0x6 },
439 { "nsh", 0x7 },
440 { "#0x08", 0x8 },
441 { "ishld", 0x9 },
442 { "ishst", 0xa },
443 { "ish", 0xb },
444 { "#0x0c", 0xc },
445 { "ld", 0xd },
446 { "st", 0xe },
447 { "sy", 0xf },
448};
449
9ed608f9
MW
450/* Table describing the operands supported by the aliases of the HINT
451 instruction.
452
453 The name column is the operand that is accepted for the alias. The value
454 column is the hint number of the alias. The list of operands is terminated
455 by NULL in the name column. */
456
457const struct aarch64_name_value_pair aarch64_hint_options[] =
458{
1e6f4800 459 { "csync", 0x11 }, /* PSB CSYNC. */
9ed608f9
MW
460 { NULL, 0x0 },
461};
462
a32c3ff8 463/* op -> op: load = 0 instruction = 1 store = 2
a06ea964
NC
464 l -> level: 1-3
465 t -> temporal: temporal (retained) = 0 non-temporal (streaming) = 1 */
a32c3ff8 466#define B(op,l,t) (((op) << 3) | (((l) - 1) << 1) | (t))
a06ea964
NC
467const struct aarch64_name_value_pair aarch64_prfops[32] =
468{
469 { "pldl1keep", B(0, 1, 0) },
470 { "pldl1strm", B(0, 1, 1) },
471 { "pldl2keep", B(0, 2, 0) },
472 { "pldl2strm", B(0, 2, 1) },
473 { "pldl3keep", B(0, 3, 0) },
474 { "pldl3strm", B(0, 3, 1) },
a1ccaec9
YZ
475 { NULL, 0x06 },
476 { NULL, 0x07 },
a32c3ff8
NC
477 { "plil1keep", B(1, 1, 0) },
478 { "plil1strm", B(1, 1, 1) },
479 { "plil2keep", B(1, 2, 0) },
480 { "plil2strm", B(1, 2, 1) },
481 { "plil3keep", B(1, 3, 0) },
482 { "plil3strm", B(1, 3, 1) },
a1ccaec9
YZ
483 { NULL, 0x0e },
484 { NULL, 0x0f },
a32c3ff8
NC
485 { "pstl1keep", B(2, 1, 0) },
486 { "pstl1strm", B(2, 1, 1) },
487 { "pstl2keep", B(2, 2, 0) },
488 { "pstl2strm", B(2, 2, 1) },
489 { "pstl3keep", B(2, 3, 0) },
490 { "pstl3strm", B(2, 3, 1) },
a1ccaec9
YZ
491 { NULL, 0x16 },
492 { NULL, 0x17 },
493 { NULL, 0x18 },
494 { NULL, 0x19 },
495 { NULL, 0x1a },
496 { NULL, 0x1b },
497 { NULL, 0x1c },
498 { NULL, 0x1d },
499 { NULL, 0x1e },
500 { NULL, 0x1f },
a06ea964
NC
501};
502#undef B
503\f
504/* Utilities on value constraint. */
505
506static inline int
507value_in_range_p (int64_t value, int low, int high)
508{
509 return (value >= low && value <= high) ? 1 : 0;
510}
511
98907a70 512/* Return true if VALUE is a multiple of ALIGN. */
a06ea964
NC
513static inline int
514value_aligned_p (int64_t value, int align)
515{
98907a70 516 return (value % align) == 0;
a06ea964
NC
517}
518
519/* A signed value fits in a field. */
520static inline int
521value_fit_signed_field_p (int64_t value, unsigned width)
522{
523 assert (width < 32);
524 if (width < sizeof (value) * 8)
525 {
526 int64_t lim = (int64_t)1 << (width - 1);
527 if (value >= -lim && value < lim)
528 return 1;
529 }
530 return 0;
531}
532
533/* An unsigned value fits in a field. */
534static inline int
535value_fit_unsigned_field_p (int64_t value, unsigned width)
536{
537 assert (width < 32);
538 if (width < sizeof (value) * 8)
539 {
540 int64_t lim = (int64_t)1 << width;
541 if (value >= 0 && value < lim)
542 return 1;
543 }
544 return 0;
545}
546
547/* Return 1 if OPERAND is SP or WSP. */
548int
549aarch64_stack_pointer_p (const aarch64_opnd_info *operand)
550{
551 return ((aarch64_get_operand_class (operand->type)
552 == AARCH64_OPND_CLASS_INT_REG)
553 && operand_maybe_stack_pointer (aarch64_operands + operand->type)
554 && operand->reg.regno == 31);
555}
556
557/* Return 1 if OPERAND is XZR or WZP. */
558int
559aarch64_zero_register_p (const aarch64_opnd_info *operand)
560{
561 return ((aarch64_get_operand_class (operand->type)
562 == AARCH64_OPND_CLASS_INT_REG)
563 && !operand_maybe_stack_pointer (aarch64_operands + operand->type)
564 && operand->reg.regno == 31);
565}
566
567/* Return true if the operand *OPERAND that has the operand code
568 OPERAND->TYPE and been qualified by OPERAND->QUALIFIER can be also
569 qualified by the qualifier TARGET. */
570
571static inline int
572operand_also_qualified_p (const struct aarch64_opnd_info *operand,
573 aarch64_opnd_qualifier_t target)
574{
575 switch (operand->qualifier)
576 {
577 case AARCH64_OPND_QLF_W:
578 if (target == AARCH64_OPND_QLF_WSP && aarch64_stack_pointer_p (operand))
579 return 1;
580 break;
581 case AARCH64_OPND_QLF_X:
582 if (target == AARCH64_OPND_QLF_SP && aarch64_stack_pointer_p (operand))
583 return 1;
584 break;
585 case AARCH64_OPND_QLF_WSP:
586 if (target == AARCH64_OPND_QLF_W
587 && operand_maybe_stack_pointer (aarch64_operands + operand->type))
588 return 1;
589 break;
590 case AARCH64_OPND_QLF_SP:
591 if (target == AARCH64_OPND_QLF_X
592 && operand_maybe_stack_pointer (aarch64_operands + operand->type))
593 return 1;
594 break;
595 default:
596 break;
597 }
598
599 return 0;
600}
601
602/* Given qualifier sequence list QSEQ_LIST and the known qualifier KNOWN_QLF
603 for operand KNOWN_IDX, return the expected qualifier for operand IDX.
604
605 Return NIL if more than one expected qualifiers are found. */
606
607aarch64_opnd_qualifier_t
608aarch64_get_expected_qualifier (const aarch64_opnd_qualifier_seq_t *qseq_list,
609 int idx,
610 const aarch64_opnd_qualifier_t known_qlf,
611 int known_idx)
612{
613 int i, saved_i;
614
615 /* Special case.
616
617 When the known qualifier is NIL, we have to assume that there is only
618 one qualifier sequence in the *QSEQ_LIST and return the corresponding
619 qualifier directly. One scenario is that for instruction
620 PRFM <prfop>, [<Xn|SP>, #:lo12:<symbol>]
621 which has only one possible valid qualifier sequence
622 NIL, S_D
623 the caller may pass NIL in KNOWN_QLF to obtain S_D so that it can
624 determine the correct relocation type (i.e. LDST64_LO12) for PRFM.
625
626 Because the qualifier NIL has dual roles in the qualifier sequence:
627 it can mean no qualifier for the operand, or the qualifer sequence is
628 not in use (when all qualifiers in the sequence are NILs), we have to
629 handle this special case here. */
630 if (known_qlf == AARCH64_OPND_NIL)
631 {
632 assert (qseq_list[0][known_idx] == AARCH64_OPND_NIL);
633 return qseq_list[0][idx];
634 }
635
636 for (i = 0, saved_i = -1; i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
637 {
638 if (qseq_list[i][known_idx] == known_qlf)
639 {
640 if (saved_i != -1)
641 /* More than one sequences are found to have KNOWN_QLF at
642 KNOWN_IDX. */
643 return AARCH64_OPND_NIL;
644 saved_i = i;
645 }
646 }
647
648 return qseq_list[saved_i][idx];
649}
650
651enum operand_qualifier_kind
652{
653 OQK_NIL,
654 OQK_OPD_VARIANT,
655 OQK_VALUE_IN_RANGE,
656 OQK_MISC,
657};
658
659/* Operand qualifier description. */
660struct operand_qualifier_data
661{
662 /* The usage of the three data fields depends on the qualifier kind. */
663 int data0;
664 int data1;
665 int data2;
666 /* Description. */
667 const char *desc;
668 /* Kind. */
669 enum operand_qualifier_kind kind;
670};
671
672/* Indexed by the operand qualifier enumerators. */
673struct operand_qualifier_data aarch64_opnd_qualifiers[] =
674{
675 {0, 0, 0, "NIL", OQK_NIL},
676
677 /* Operand variant qualifiers.
678 First 3 fields:
679 element size, number of elements and common value for encoding. */
680
681 {4, 1, 0x0, "w", OQK_OPD_VARIANT},
682 {8, 1, 0x1, "x", OQK_OPD_VARIANT},
683 {4, 1, 0x0, "wsp", OQK_OPD_VARIANT},
684 {8, 1, 0x1, "sp", OQK_OPD_VARIANT},
685
686 {1, 1, 0x0, "b", OQK_OPD_VARIANT},
687 {2, 1, 0x1, "h", OQK_OPD_VARIANT},
688 {4, 1, 0x2, "s", OQK_OPD_VARIANT},
689 {8, 1, 0x3, "d", OQK_OPD_VARIANT},
690 {16, 1, 0x4, "q", OQK_OPD_VARIANT},
691
692 {1, 8, 0x0, "8b", OQK_OPD_VARIANT},
693 {1, 16, 0x1, "16b", OQK_OPD_VARIANT},
3067d3b9 694 {2, 2, 0x0, "2h", OQK_OPD_VARIANT},
a06ea964
NC
695 {2, 4, 0x2, "4h", OQK_OPD_VARIANT},
696 {2, 8, 0x3, "8h", OQK_OPD_VARIANT},
697 {4, 2, 0x4, "2s", OQK_OPD_VARIANT},
698 {4, 4, 0x5, "4s", OQK_OPD_VARIANT},
699 {8, 1, 0x6, "1d", OQK_OPD_VARIANT},
700 {8, 2, 0x7, "2d", OQK_OPD_VARIANT},
701 {16, 1, 0x8, "1q", OQK_OPD_VARIANT},
702
d50c751e
RS
703 {0, 0, 0, "z", OQK_OPD_VARIANT},
704 {0, 0, 0, "m", OQK_OPD_VARIANT},
705
a06ea964
NC
706 /* Qualifiers constraining the value range.
707 First 3 fields:
708 Lower bound, higher bound, unused. */
709
710 {0, 7, 0, "imm_0_7" , OQK_VALUE_IN_RANGE},
711 {0, 15, 0, "imm_0_15", OQK_VALUE_IN_RANGE},
712 {0, 31, 0, "imm_0_31", OQK_VALUE_IN_RANGE},
713 {0, 63, 0, "imm_0_63", OQK_VALUE_IN_RANGE},
714 {1, 32, 0, "imm_1_32", OQK_VALUE_IN_RANGE},
715 {1, 64, 0, "imm_1_64", OQK_VALUE_IN_RANGE},
716
717 /* Qualifiers for miscellaneous purpose.
718 First 3 fields:
719 unused, unused and unused. */
720
721 {0, 0, 0, "lsl", 0},
722 {0, 0, 0, "msl", 0},
723
724 {0, 0, 0, "retrieving", 0},
725};
726
727static inline bfd_boolean
728operand_variant_qualifier_p (aarch64_opnd_qualifier_t qualifier)
729{
730 return (aarch64_opnd_qualifiers[qualifier].kind == OQK_OPD_VARIANT)
731 ? TRUE : FALSE;
732}
733
734static inline bfd_boolean
735qualifier_value_in_range_constraint_p (aarch64_opnd_qualifier_t qualifier)
736{
737 return (aarch64_opnd_qualifiers[qualifier].kind == OQK_VALUE_IN_RANGE)
738 ? TRUE : FALSE;
739}
740
741const char*
742aarch64_get_qualifier_name (aarch64_opnd_qualifier_t qualifier)
743{
744 return aarch64_opnd_qualifiers[qualifier].desc;
745}
746
747/* Given an operand qualifier, return the expected data element size
748 of a qualified operand. */
749unsigned char
750aarch64_get_qualifier_esize (aarch64_opnd_qualifier_t qualifier)
751{
752 assert (operand_variant_qualifier_p (qualifier) == TRUE);
753 return aarch64_opnd_qualifiers[qualifier].data0;
754}
755
756unsigned char
757aarch64_get_qualifier_nelem (aarch64_opnd_qualifier_t qualifier)
758{
759 assert (operand_variant_qualifier_p (qualifier) == TRUE);
760 return aarch64_opnd_qualifiers[qualifier].data1;
761}
762
763aarch64_insn
764aarch64_get_qualifier_standard_value (aarch64_opnd_qualifier_t qualifier)
765{
766 assert (operand_variant_qualifier_p (qualifier) == TRUE);
767 return aarch64_opnd_qualifiers[qualifier].data2;
768}
769
770static int
771get_lower_bound (aarch64_opnd_qualifier_t qualifier)
772{
773 assert (qualifier_value_in_range_constraint_p (qualifier) == TRUE);
774 return aarch64_opnd_qualifiers[qualifier].data0;
775}
776
777static int
778get_upper_bound (aarch64_opnd_qualifier_t qualifier)
779{
780 assert (qualifier_value_in_range_constraint_p (qualifier) == TRUE);
781 return aarch64_opnd_qualifiers[qualifier].data1;
782}
783
784#ifdef DEBUG_AARCH64
785void
786aarch64_verbose (const char *str, ...)
787{
788 va_list ap;
789 va_start (ap, str);
790 printf ("#### ");
791 vprintf (str, ap);
792 printf ("\n");
793 va_end (ap);
794}
795
796static inline void
797dump_qualifier_sequence (const aarch64_opnd_qualifier_t *qualifier)
798{
799 int i;
800 printf ("#### \t");
801 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i, ++qualifier)
802 printf ("%s,", aarch64_get_qualifier_name (*qualifier));
803 printf ("\n");
804}
805
806static void
807dump_match_qualifiers (const struct aarch64_opnd_info *opnd,
808 const aarch64_opnd_qualifier_t *qualifier)
809{
810 int i;
811 aarch64_opnd_qualifier_t curr[AARCH64_MAX_OPND_NUM];
812
813 aarch64_verbose ("dump_match_qualifiers:");
814 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
815 curr[i] = opnd[i].qualifier;
816 dump_qualifier_sequence (curr);
817 aarch64_verbose ("against");
818 dump_qualifier_sequence (qualifier);
819}
820#endif /* DEBUG_AARCH64 */
821
822/* TODO improve this, we can have an extra field at the runtime to
823 store the number of operands rather than calculating it every time. */
824
825int
826aarch64_num_of_operands (const aarch64_opcode *opcode)
827{
828 int i = 0;
829 const enum aarch64_opnd *opnds = opcode->operands;
830 while (opnds[i++] != AARCH64_OPND_NIL)
831 ;
832 --i;
833 assert (i >= 0 && i <= AARCH64_MAX_OPND_NUM);
834 return i;
835}
836
837/* Find the best matched qualifier sequence in *QUALIFIERS_LIST for INST.
838 If succeeds, fill the found sequence in *RET, return 1; otherwise return 0.
839
840 N.B. on the entry, it is very likely that only some operands in *INST
841 have had their qualifiers been established.
842
843 If STOP_AT is not -1, the function will only try to match
844 the qualifier sequence for operands before and including the operand
845 of index STOP_AT; and on success *RET will only be filled with the first
846 (STOP_AT+1) qualifiers.
847
848 A couple examples of the matching algorithm:
849
850 X,W,NIL should match
851 X,W,NIL
852
853 NIL,NIL should match
854 X ,NIL
855
856 Apart from serving the main encoding routine, this can also be called
857 during or after the operand decoding. */
858
859int
860aarch64_find_best_match (const aarch64_inst *inst,
861 const aarch64_opnd_qualifier_seq_t *qualifiers_list,
862 int stop_at, aarch64_opnd_qualifier_t *ret)
863{
864 int found = 0;
865 int i, num_opnds;
866 const aarch64_opnd_qualifier_t *qualifiers;
867
868 num_opnds = aarch64_num_of_operands (inst->opcode);
869 if (num_opnds == 0)
870 {
871 DEBUG_TRACE ("SUCCEED: no operand");
872 return 1;
873 }
874
875 if (stop_at < 0 || stop_at >= num_opnds)
876 stop_at = num_opnds - 1;
877
878 /* For each pattern. */
879 for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i, ++qualifiers_list)
880 {
881 int j;
882 qualifiers = *qualifiers_list;
883
884 /* Start as positive. */
885 found = 1;
886
887 DEBUG_TRACE ("%d", i);
888#ifdef DEBUG_AARCH64
889 if (debug_dump)
890 dump_match_qualifiers (inst->operands, qualifiers);
891#endif
892
893 /* Most opcodes has much fewer patterns in the list.
894 First NIL qualifier indicates the end in the list. */
895 if (empty_qualifier_sequence_p (qualifiers) == TRUE)
896 {
897 DEBUG_TRACE_IF (i == 0, "SUCCEED: empty qualifier list");
898 if (i)
899 found = 0;
900 break;
901 }
902
903 for (j = 0; j < num_opnds && j <= stop_at; ++j, ++qualifiers)
904 {
905 if (inst->operands[j].qualifier == AARCH64_OPND_QLF_NIL)
906 {
907 /* Either the operand does not have qualifier, or the qualifier
908 for the operand needs to be deduced from the qualifier
909 sequence.
910 In the latter case, any constraint checking related with
911 the obtained qualifier should be done later in
912 operand_general_constraint_met_p. */
913 continue;
914 }
915 else if (*qualifiers != inst->operands[j].qualifier)
916 {
917 /* Unless the target qualifier can also qualify the operand
918 (which has already had a non-nil qualifier), non-equal
919 qualifiers are generally un-matched. */
920 if (operand_also_qualified_p (inst->operands + j, *qualifiers))
921 continue;
922 else
923 {
924 found = 0;
925 break;
926 }
927 }
928 else
929 continue; /* Equal qualifiers are certainly matched. */
930 }
931
932 /* Qualifiers established. */
933 if (found == 1)
934 break;
935 }
936
937 if (found == 1)
938 {
939 /* Fill the result in *RET. */
940 int j;
941 qualifiers = *qualifiers_list;
942
943 DEBUG_TRACE ("complete qualifiers using list %d", i);
944#ifdef DEBUG_AARCH64
945 if (debug_dump)
946 dump_qualifier_sequence (qualifiers);
947#endif
948
949 for (j = 0; j <= stop_at; ++j, ++qualifiers)
950 ret[j] = *qualifiers;
951 for (; j < AARCH64_MAX_OPND_NUM; ++j)
952 ret[j] = AARCH64_OPND_QLF_NIL;
953
954 DEBUG_TRACE ("SUCCESS");
955 return 1;
956 }
957
958 DEBUG_TRACE ("FAIL");
959 return 0;
960}
961
962/* Operand qualifier matching and resolving.
963
964 Return 1 if the operand qualifier(s) in *INST match one of the qualifier
965 sequences in INST->OPCODE->qualifiers_list; otherwise return 0.
966
967 if UPDATE_P == TRUE, update the qualifier(s) in *INST after the matching
968 succeeds. */
969
970static int
971match_operands_qualifier (aarch64_inst *inst, bfd_boolean update_p)
972{
4989adac 973 int i, nops;
a06ea964
NC
974 aarch64_opnd_qualifier_seq_t qualifiers;
975
976 if (!aarch64_find_best_match (inst, inst->opcode->qualifiers_list, -1,
977 qualifiers))
978 {
979 DEBUG_TRACE ("matching FAIL");
980 return 0;
981 }
982
4989adac
RS
983 if (inst->opcode->flags & F_STRICT)
984 {
985 /* Require an exact qualifier match, even for NIL qualifiers. */
986 nops = aarch64_num_of_operands (inst->opcode);
987 for (i = 0; i < nops; ++i)
988 if (inst->operands[i].qualifier != qualifiers[i])
989 return FALSE;
990 }
991
a06ea964
NC
992 /* Update the qualifiers. */
993 if (update_p == TRUE)
994 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
995 {
996 if (inst->opcode->operands[i] == AARCH64_OPND_NIL)
997 break;
998 DEBUG_TRACE_IF (inst->operands[i].qualifier != qualifiers[i],
999 "update %s with %s for operand %d",
1000 aarch64_get_qualifier_name (inst->operands[i].qualifier),
1001 aarch64_get_qualifier_name (qualifiers[i]), i);
1002 inst->operands[i].qualifier = qualifiers[i];
1003 }
1004
1005 DEBUG_TRACE ("matching SUCCESS");
1006 return 1;
1007}
1008
1009/* Return TRUE if VALUE is a wide constant that can be moved into a general
1010 register by MOVZ.
1011
1012 IS32 indicates whether value is a 32-bit immediate or not.
1013 If SHIFT_AMOUNT is not NULL, on the return of TRUE, the logical left shift
1014 amount will be returned in *SHIFT_AMOUNT. */
1015
1016bfd_boolean
1017aarch64_wide_constant_p (int64_t value, int is32, unsigned int *shift_amount)
1018{
1019 int amount;
1020
1021 DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 ")", value, value);
1022
1023 if (is32)
1024 {
1025 /* Allow all zeros or all ones in top 32-bits, so that
1026 32-bit constant expressions like ~0x80000000 are
1027 permitted. */
1028 uint64_t ext = value;
1029 if (ext >> 32 != 0 && ext >> 32 != (uint64_t) 0xffffffff)
1030 /* Immediate out of range. */
1031 return FALSE;
1032 value &= (int64_t) 0xffffffff;
1033 }
1034
1035 /* first, try movz then movn */
1036 amount = -1;
1037 if ((value & ((int64_t) 0xffff << 0)) == value)
1038 amount = 0;
1039 else if ((value & ((int64_t) 0xffff << 16)) == value)
1040 amount = 16;
1041 else if (!is32 && (value & ((int64_t) 0xffff << 32)) == value)
1042 amount = 32;
1043 else if (!is32 && (value & ((int64_t) 0xffff << 48)) == value)
1044 amount = 48;
1045
1046 if (amount == -1)
1047 {
1048 DEBUG_TRACE ("exit FALSE with 0x%" PRIx64 "(%" PRIi64 ")", value, value);
1049 return FALSE;
1050 }
1051
1052 if (shift_amount != NULL)
1053 *shift_amount = amount;
1054
1055 DEBUG_TRACE ("exit TRUE with amount %d", amount);
1056
1057 return TRUE;
1058}
1059
1060/* Build the accepted values for immediate logical SIMD instructions.
1061
1062 The standard encodings of the immediate value are:
1063 N imms immr SIMD size R S
1064 1 ssssss rrrrrr 64 UInt(rrrrrr) UInt(ssssss)
1065 0 0sssss 0rrrrr 32 UInt(rrrrr) UInt(sssss)
1066 0 10ssss 00rrrr 16 UInt(rrrr) UInt(ssss)
1067 0 110sss 000rrr 8 UInt(rrr) UInt(sss)
1068 0 1110ss 0000rr 4 UInt(rr) UInt(ss)
1069 0 11110s 00000r 2 UInt(r) UInt(s)
1070 where all-ones value of S is reserved.
1071
1072 Let's call E the SIMD size.
1073
1074 The immediate value is: S+1 bits '1' rotated to the right by R.
1075
1076 The total of valid encodings is 64*63 + 32*31 + ... + 2*1 = 5334
1077 (remember S != E - 1). */
1078
1079#define TOTAL_IMM_NB 5334
1080
1081typedef struct
1082{
1083 uint64_t imm;
1084 aarch64_insn encoding;
1085} simd_imm_encoding;
1086
1087static simd_imm_encoding simd_immediates[TOTAL_IMM_NB];
1088
1089static int
1090simd_imm_encoding_cmp(const void *i1, const void *i2)
1091{
1092 const simd_imm_encoding *imm1 = (const simd_imm_encoding *)i1;
1093 const simd_imm_encoding *imm2 = (const simd_imm_encoding *)i2;
1094
1095 if (imm1->imm < imm2->imm)
1096 return -1;
1097 if (imm1->imm > imm2->imm)
1098 return +1;
1099 return 0;
1100}
1101
1102/* immediate bitfield standard encoding
1103 imm13<12> imm13<5:0> imm13<11:6> SIMD size R S
1104 1 ssssss rrrrrr 64 rrrrrr ssssss
1105 0 0sssss 0rrrrr 32 rrrrr sssss
1106 0 10ssss 00rrrr 16 rrrr ssss
1107 0 110sss 000rrr 8 rrr sss
1108 0 1110ss 0000rr 4 rr ss
1109 0 11110s 00000r 2 r s */
1110static inline int
1111encode_immediate_bitfield (int is64, uint32_t s, uint32_t r)
1112{
1113 return (is64 << 12) | (r << 6) | s;
1114}
1115
1116static void
1117build_immediate_table (void)
1118{
1119 uint32_t log_e, e, s, r, s_mask;
1120 uint64_t mask, imm;
1121 int nb_imms;
1122 int is64;
1123
1124 nb_imms = 0;
1125 for (log_e = 1; log_e <= 6; log_e++)
1126 {
1127 /* Get element size. */
1128 e = 1u << log_e;
1129 if (log_e == 6)
1130 {
1131 is64 = 1;
1132 mask = 0xffffffffffffffffull;
1133 s_mask = 0;
1134 }
1135 else
1136 {
1137 is64 = 0;
1138 mask = (1ull << e) - 1;
1139 /* log_e s_mask
1140 1 ((1 << 4) - 1) << 2 = 111100
1141 2 ((1 << 3) - 1) << 3 = 111000
1142 3 ((1 << 2) - 1) << 4 = 110000
1143 4 ((1 << 1) - 1) << 5 = 100000
1144 5 ((1 << 0) - 1) << 6 = 000000 */
1145 s_mask = ((1u << (5 - log_e)) - 1) << (log_e + 1);
1146 }
1147 for (s = 0; s < e - 1; s++)
1148 for (r = 0; r < e; r++)
1149 {
1150 /* s+1 consecutive bits to 1 (s < 63) */
1151 imm = (1ull << (s + 1)) - 1;
1152 /* rotate right by r */
1153 if (r != 0)
1154 imm = (imm >> r) | ((imm << (e - r)) & mask);
1155 /* replicate the constant depending on SIMD size */
1156 switch (log_e)
1157 {
1158 case 1: imm = (imm << 2) | imm;
1a0670f3 1159 /* Fall through. */
a06ea964 1160 case 2: imm = (imm << 4) | imm;
1a0670f3 1161 /* Fall through. */
a06ea964 1162 case 3: imm = (imm << 8) | imm;
1a0670f3 1163 /* Fall through. */
a06ea964 1164 case 4: imm = (imm << 16) | imm;
1a0670f3 1165 /* Fall through. */
a06ea964 1166 case 5: imm = (imm << 32) | imm;
1a0670f3 1167 /* Fall through. */
a06ea964
NC
1168 case 6: break;
1169 default: abort ();
1170 }
1171 simd_immediates[nb_imms].imm = imm;
1172 simd_immediates[nb_imms].encoding =
1173 encode_immediate_bitfield(is64, s | s_mask, r);
1174 nb_imms++;
1175 }
1176 }
1177 assert (nb_imms == TOTAL_IMM_NB);
1178 qsort(simd_immediates, nb_imms,
1179 sizeof(simd_immediates[0]), simd_imm_encoding_cmp);
1180}
1181
1182/* Return TRUE if VALUE is a valid logical immediate, i.e. bitmask, that can
1183 be accepted by logical (immediate) instructions
1184 e.g. ORR <Xd|SP>, <Xn>, #<imm>.
1185
42408347 1186 ESIZE is the number of bytes in the decoded immediate value.
a06ea964
NC
1187 If ENCODING is not NULL, on the return of TRUE, the standard encoding for
1188 VALUE will be returned in *ENCODING. */
1189
1190bfd_boolean
42408347 1191aarch64_logical_immediate_p (uint64_t value, int esize, aarch64_insn *encoding)
a06ea964
NC
1192{
1193 simd_imm_encoding imm_enc;
1194 const simd_imm_encoding *imm_encoding;
1195 static bfd_boolean initialized = FALSE;
42408347
RS
1196 uint64_t upper;
1197 int i;
a06ea964
NC
1198
1199 DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 "), is32: %d", value,
1200 value, is32);
1201
1202 if (initialized == FALSE)
1203 {
1204 build_immediate_table ();
1205 initialized = TRUE;
1206 }
1207
42408347
RS
1208 /* Allow all zeros or all ones in top bits, so that
1209 constant expressions like ~1 are permitted. */
1210 upper = (uint64_t) -1 << (esize * 4) << (esize * 4);
1211 if ((value & ~upper) != value && (value | upper) != value)
1212 return FALSE;
7e105031 1213
42408347
RS
1214 /* Replicate to a full 64-bit value. */
1215 value &= ~upper;
1216 for (i = esize * 8; i < 64; i *= 2)
1217 value |= (value << i);
a06ea964
NC
1218
1219 imm_enc.imm = value;
1220 imm_encoding = (const simd_imm_encoding *)
1221 bsearch(&imm_enc, simd_immediates, TOTAL_IMM_NB,
1222 sizeof(simd_immediates[0]), simd_imm_encoding_cmp);
1223 if (imm_encoding == NULL)
1224 {
1225 DEBUG_TRACE ("exit with FALSE");
1226 return FALSE;
1227 }
1228 if (encoding != NULL)
1229 *encoding = imm_encoding->encoding;
1230 DEBUG_TRACE ("exit with TRUE");
1231 return TRUE;
1232}
1233
1234/* If 64-bit immediate IMM is in the format of
1235 "aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh",
1236 where a, b, c, d, e, f, g and h are independently 0 or 1, return an integer
1237 of value "abcdefgh". Otherwise return -1. */
1238int
1239aarch64_shrink_expanded_imm8 (uint64_t imm)
1240{
1241 int i, ret;
1242 uint32_t byte;
1243
1244 ret = 0;
1245 for (i = 0; i < 8; i++)
1246 {
1247 byte = (imm >> (8 * i)) & 0xff;
1248 if (byte == 0xff)
1249 ret |= 1 << i;
1250 else if (byte != 0x00)
1251 return -1;
1252 }
1253 return ret;
1254}
1255
1256/* Utility inline functions for operand_general_constraint_met_p. */
1257
1258static inline void
1259set_error (aarch64_operand_error *mismatch_detail,
1260 enum aarch64_operand_error_kind kind, int idx,
1261 const char* error)
1262{
1263 if (mismatch_detail == NULL)
1264 return;
1265 mismatch_detail->kind = kind;
1266 mismatch_detail->index = idx;
1267 mismatch_detail->error = error;
1268}
1269
4e50d5f8
YZ
1270static inline void
1271set_syntax_error (aarch64_operand_error *mismatch_detail, int idx,
1272 const char* error)
1273{
1274 if (mismatch_detail == NULL)
1275 return;
1276 set_error (mismatch_detail, AARCH64_OPDE_SYNTAX_ERROR, idx, error);
1277}
1278
a06ea964
NC
1279static inline void
1280set_out_of_range_error (aarch64_operand_error *mismatch_detail,
1281 int idx, int lower_bound, int upper_bound,
1282 const char* error)
1283{
1284 if (mismatch_detail == NULL)
1285 return;
1286 set_error (mismatch_detail, AARCH64_OPDE_OUT_OF_RANGE, idx, error);
1287 mismatch_detail->data[0] = lower_bound;
1288 mismatch_detail->data[1] = upper_bound;
1289}
1290
1291static inline void
1292set_imm_out_of_range_error (aarch64_operand_error *mismatch_detail,
1293 int idx, int lower_bound, int upper_bound)
1294{
1295 if (mismatch_detail == NULL)
1296 return;
1297 set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1298 _("immediate value"));
1299}
1300
1301static inline void
1302set_offset_out_of_range_error (aarch64_operand_error *mismatch_detail,
1303 int idx, int lower_bound, int upper_bound)
1304{
1305 if (mismatch_detail == NULL)
1306 return;
1307 set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1308 _("immediate offset"));
1309}
1310
1311static inline void
1312set_regno_out_of_range_error (aarch64_operand_error *mismatch_detail,
1313 int idx, int lower_bound, int upper_bound)
1314{
1315 if (mismatch_detail == NULL)
1316 return;
1317 set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1318 _("register number"));
1319}
1320
1321static inline void
1322set_elem_idx_out_of_range_error (aarch64_operand_error *mismatch_detail,
1323 int idx, int lower_bound, int upper_bound)
1324{
1325 if (mismatch_detail == NULL)
1326 return;
1327 set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1328 _("register element index"));
1329}
1330
1331static inline void
1332set_sft_amount_out_of_range_error (aarch64_operand_error *mismatch_detail,
1333 int idx, int lower_bound, int upper_bound)
1334{
1335 if (mismatch_detail == NULL)
1336 return;
1337 set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1338 _("shift amount"));
1339}
1340
2442d846
RS
1341/* Report that the MUL modifier in operand IDX should be in the range
1342 [LOWER_BOUND, UPPER_BOUND]. */
1343static inline void
1344set_multiplier_out_of_range_error (aarch64_operand_error *mismatch_detail,
1345 int idx, int lower_bound, int upper_bound)
1346{
1347 if (mismatch_detail == NULL)
1348 return;
1349 set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1350 _("multiplier"));
1351}
1352
a06ea964
NC
1353static inline void
1354set_unaligned_error (aarch64_operand_error *mismatch_detail, int idx,
1355 int alignment)
1356{
1357 if (mismatch_detail == NULL)
1358 return;
1359 set_error (mismatch_detail, AARCH64_OPDE_UNALIGNED, idx, NULL);
1360 mismatch_detail->data[0] = alignment;
1361}
1362
1363static inline void
1364set_reg_list_error (aarch64_operand_error *mismatch_detail, int idx,
1365 int expected_num)
1366{
1367 if (mismatch_detail == NULL)
1368 return;
1369 set_error (mismatch_detail, AARCH64_OPDE_REG_LIST, idx, NULL);
1370 mismatch_detail->data[0] = expected_num;
1371}
1372
1373static inline void
1374set_other_error (aarch64_operand_error *mismatch_detail, int idx,
1375 const char* error)
1376{
1377 if (mismatch_detail == NULL)
1378 return;
1379 set_error (mismatch_detail, AARCH64_OPDE_OTHER_ERROR, idx, error);
1380}
1381
1382/* General constraint checking based on operand code.
1383
1384 Return 1 if OPNDS[IDX] meets the general constraint of operand code TYPE
1385 as the IDXth operand of opcode OPCODE. Otherwise return 0.
1386
1387 This function has to be called after the qualifiers for all operands
1388 have been resolved.
1389
1390 Mismatching error message is returned in *MISMATCH_DETAIL upon request,
1391 i.e. when MISMATCH_DETAIL is non-NULL. This avoids the generation
1392 of error message during the disassembling where error message is not
1393 wanted. We avoid the dynamic construction of strings of error messages
1394 here (i.e. in libopcodes), as it is costly and complicated; instead, we
1395 use a combination of error code, static string and some integer data to
1396 represent an error. */
1397
1398static int
1399operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
1400 enum aarch64_opnd type,
1401 const aarch64_opcode *opcode,
1402 aarch64_operand_error *mismatch_detail)
1403{
e950b345 1404 unsigned num, modifiers, shift;
a06ea964 1405 unsigned char size;
4df068de 1406 int64_t imm, min_value, max_value;
e950b345 1407 uint64_t uvalue, mask;
a06ea964
NC
1408 const aarch64_opnd_info *opnd = opnds + idx;
1409 aarch64_opnd_qualifier_t qualifier = opnd->qualifier;
1410
1411 assert (opcode->operands[idx] == opnd->type && opnd->type == type);
1412
1413 switch (aarch64_operands[type].op_class)
1414 {
1415 case AARCH64_OPND_CLASS_INT_REG:
ee804238
JW
1416 /* Check pair reg constraints for cas* instructions. */
1417 if (type == AARCH64_OPND_PAIRREG)
1418 {
1419 assert (idx == 1 || idx == 3);
1420 if (opnds[idx - 1].reg.regno % 2 != 0)
1421 {
1422 set_syntax_error (mismatch_detail, idx - 1,
1423 _("reg pair must start from even reg"));
1424 return 0;
1425 }
1426 if (opnds[idx].reg.regno != opnds[idx - 1].reg.regno + 1)
1427 {
1428 set_syntax_error (mismatch_detail, idx,
1429 _("reg pair must be contiguous"));
1430 return 0;
1431 }
1432 break;
1433 }
1434
a06ea964
NC
1435 /* <Xt> may be optional in some IC and TLBI instructions. */
1436 if (type == AARCH64_OPND_Rt_SYS)
1437 {
1438 assert (idx == 1 && (aarch64_get_operand_class (opnds[0].type)
1439 == AARCH64_OPND_CLASS_SYSTEM));
ea2deeec
MW
1440 if (opnds[1].present
1441 && !aarch64_sys_ins_reg_has_xt (opnds[0].sysins_op))
a06ea964
NC
1442 {
1443 set_other_error (mismatch_detail, idx, _("extraneous register"));
1444 return 0;
1445 }
ea2deeec
MW
1446 if (!opnds[1].present
1447 && aarch64_sys_ins_reg_has_xt (opnds[0].sysins_op))
a06ea964
NC
1448 {
1449 set_other_error (mismatch_detail, idx, _("missing register"));
1450 return 0;
1451 }
1452 }
1453 switch (qualifier)
1454 {
1455 case AARCH64_OPND_QLF_WSP:
1456 case AARCH64_OPND_QLF_SP:
1457 if (!aarch64_stack_pointer_p (opnd))
1458 {
1459 set_other_error (mismatch_detail, idx,
1460 _("stack pointer register expected"));
1461 return 0;
1462 }
1463 break;
1464 default:
1465 break;
1466 }
1467 break;
1468
f11ad6bc
RS
1469 case AARCH64_OPND_CLASS_SVE_REG:
1470 switch (type)
1471 {
1472 case AARCH64_OPND_SVE_Zn_INDEX:
1473 size = aarch64_get_qualifier_esize (opnd->qualifier);
1474 if (!value_in_range_p (opnd->reglane.index, 0, 64 / size - 1))
1475 {
1476 set_elem_idx_out_of_range_error (mismatch_detail, idx,
1477 0, 64 / size - 1);
1478 return 0;
1479 }
1480 break;
1481
1482 case AARCH64_OPND_SVE_ZnxN:
1483 case AARCH64_OPND_SVE_ZtxN:
1484 if (opnd->reglist.num_regs != get_opcode_dependent_value (opcode))
1485 {
1486 set_other_error (mismatch_detail, idx,
1487 _("invalid register list"));
1488 return 0;
1489 }
1490 break;
1491
1492 default:
1493 break;
1494 }
1495 break;
1496
1497 case AARCH64_OPND_CLASS_PRED_REG:
1498 if (opnd->reg.regno >= 8
1499 && get_operand_fields_width (get_operand_from_code (type)) == 3)
1500 {
1501 set_other_error (mismatch_detail, idx, _("p0-p7 expected"));
1502 return 0;
1503 }
1504 break;
1505
68a64283
YZ
1506 case AARCH64_OPND_CLASS_COND:
1507 if (type == AARCH64_OPND_COND1
1508 && (opnds[idx].cond->value & 0xe) == 0xe)
1509 {
1510 /* Not allow AL or NV. */
1511 set_syntax_error (mismatch_detail, idx, NULL);
1512 }
1513 break;
1514
a06ea964
NC
1515 case AARCH64_OPND_CLASS_ADDRESS:
1516 /* Check writeback. */
1517 switch (opcode->iclass)
1518 {
1519 case ldst_pos:
1520 case ldst_unscaled:
1521 case ldstnapair_offs:
1522 case ldstpair_off:
1523 case ldst_unpriv:
1524 if (opnd->addr.writeback == 1)
1525 {
4e50d5f8
YZ
1526 set_syntax_error (mismatch_detail, idx,
1527 _("unexpected address writeback"));
a06ea964
NC
1528 return 0;
1529 }
1530 break;
1531 case ldst_imm9:
1532 case ldstpair_indexed:
1533 case asisdlsep:
1534 case asisdlsop:
1535 if (opnd->addr.writeback == 0)
1536 {
4e50d5f8
YZ
1537 set_syntax_error (mismatch_detail, idx,
1538 _("address writeback expected"));
a06ea964
NC
1539 return 0;
1540 }
1541 break;
1542 default:
1543 assert (opnd->addr.writeback == 0);
1544 break;
1545 }
1546 switch (type)
1547 {
1548 case AARCH64_OPND_ADDR_SIMM7:
1549 /* Scaled signed 7 bits immediate offset. */
1550 /* Get the size of the data element that is accessed, which may be
1551 different from that of the source register size,
1552 e.g. in strb/ldrb. */
1553 size = aarch64_get_qualifier_esize (opnd->qualifier);
1554 if (!value_in_range_p (opnd->addr.offset.imm, -64 * size, 63 * size))
1555 {
1556 set_offset_out_of_range_error (mismatch_detail, idx,
1557 -64 * size, 63 * size);
1558 return 0;
1559 }
1560 if (!value_aligned_p (opnd->addr.offset.imm, size))
1561 {
1562 set_unaligned_error (mismatch_detail, idx, size);
1563 return 0;
1564 }
1565 break;
1566 case AARCH64_OPND_ADDR_SIMM9:
1567 /* Unscaled signed 9 bits immediate offset. */
1568 if (!value_in_range_p (opnd->addr.offset.imm, -256, 255))
1569 {
1570 set_offset_out_of_range_error (mismatch_detail, idx, -256, 255);
1571 return 0;
1572 }
1573 break;
1574
1575 case AARCH64_OPND_ADDR_SIMM9_2:
1576 /* Unscaled signed 9 bits immediate offset, which has to be negative
1577 or unaligned. */
1578 size = aarch64_get_qualifier_esize (qualifier);
1579 if ((value_in_range_p (opnd->addr.offset.imm, 0, 255)
1580 && !value_aligned_p (opnd->addr.offset.imm, size))
1581 || value_in_range_p (opnd->addr.offset.imm, -256, -1))
1582 return 1;
1583 set_other_error (mismatch_detail, idx,
1584 _("negative or unaligned offset expected"));
1585 return 0;
1586
1587 case AARCH64_OPND_SIMD_ADDR_POST:
1588 /* AdvSIMD load/store multiple structures, post-index. */
1589 assert (idx == 1);
1590 if (opnd->addr.offset.is_reg)
1591 {
1592 if (value_in_range_p (opnd->addr.offset.regno, 0, 30))
1593 return 1;
1594 else
1595 {
1596 set_other_error (mismatch_detail, idx,
1597 _("invalid register offset"));
1598 return 0;
1599 }
1600 }
1601 else
1602 {
1603 const aarch64_opnd_info *prev = &opnds[idx-1];
1604 unsigned num_bytes; /* total number of bytes transferred. */
1605 /* The opcode dependent area stores the number of elements in
1606 each structure to be loaded/stored. */
1607 int is_ld1r = get_opcode_dependent_value (opcode) == 1;
1608 if (opcode->operands[0] == AARCH64_OPND_LVt_AL)
1609 /* Special handling of loading single structure to all lane. */
1610 num_bytes = (is_ld1r ? 1 : prev->reglist.num_regs)
1611 * aarch64_get_qualifier_esize (prev->qualifier);
1612 else
1613 num_bytes = prev->reglist.num_regs
1614 * aarch64_get_qualifier_esize (prev->qualifier)
1615 * aarch64_get_qualifier_nelem (prev->qualifier);
1616 if ((int) num_bytes != opnd->addr.offset.imm)
1617 {
1618 set_other_error (mismatch_detail, idx,
1619 _("invalid post-increment amount"));
1620 return 0;
1621 }
1622 }
1623 break;
1624
1625 case AARCH64_OPND_ADDR_REGOFF:
1626 /* Get the size of the data element that is accessed, which may be
1627 different from that of the source register size,
1628 e.g. in strb/ldrb. */
1629 size = aarch64_get_qualifier_esize (opnd->qualifier);
1630 /* It is either no shift or shift by the binary logarithm of SIZE. */
1631 if (opnd->shifter.amount != 0
1632 && opnd->shifter.amount != (int)get_logsz (size))
1633 {
1634 set_other_error (mismatch_detail, idx,
1635 _("invalid shift amount"));
1636 return 0;
1637 }
1638 /* Only UXTW, LSL, SXTW and SXTX are the accepted extending
1639 operators. */
1640 switch (opnd->shifter.kind)
1641 {
1642 case AARCH64_MOD_UXTW:
1643 case AARCH64_MOD_LSL:
1644 case AARCH64_MOD_SXTW:
1645 case AARCH64_MOD_SXTX: break;
1646 default:
1647 set_other_error (mismatch_detail, idx,
1648 _("invalid extend/shift operator"));
1649 return 0;
1650 }
1651 break;
1652
1653 case AARCH64_OPND_ADDR_UIMM12:
1654 imm = opnd->addr.offset.imm;
1655 /* Get the size of the data element that is accessed, which may be
1656 different from that of the source register size,
1657 e.g. in strb/ldrb. */
1658 size = aarch64_get_qualifier_esize (qualifier);
1659 if (!value_in_range_p (opnd->addr.offset.imm, 0, 4095 * size))
1660 {
1661 set_offset_out_of_range_error (mismatch_detail, idx,
1662 0, 4095 * size);
1663 return 0;
1664 }
9de794e1 1665 if (!value_aligned_p (opnd->addr.offset.imm, size))
a06ea964
NC
1666 {
1667 set_unaligned_error (mismatch_detail, idx, size);
1668 return 0;
1669 }
1670 break;
1671
1672 case AARCH64_OPND_ADDR_PCREL14:
1673 case AARCH64_OPND_ADDR_PCREL19:
1674 case AARCH64_OPND_ADDR_PCREL21:
1675 case AARCH64_OPND_ADDR_PCREL26:
1676 imm = opnd->imm.value;
1677 if (operand_need_shift_by_two (get_operand_from_code (type)))
1678 {
1679 /* The offset value in a PC-relative branch instruction is alway
1680 4-byte aligned and is encoded without the lowest 2 bits. */
1681 if (!value_aligned_p (imm, 4))
1682 {
1683 set_unaligned_error (mismatch_detail, idx, 4);
1684 return 0;
1685 }
1686 /* Right shift by 2 so that we can carry out the following check
1687 canonically. */
1688 imm >>= 2;
1689 }
1690 size = get_operand_fields_width (get_operand_from_code (type));
1691 if (!value_fit_signed_field_p (imm, size))
1692 {
1693 set_other_error (mismatch_detail, idx,
1694 _("immediate out of range"));
1695 return 0;
1696 }
1697 break;
1698
98907a70
RS
1699 case AARCH64_OPND_SVE_ADDR_RI_S4xVL:
1700 case AARCH64_OPND_SVE_ADDR_RI_S4x2xVL:
1701 case AARCH64_OPND_SVE_ADDR_RI_S4x3xVL:
1702 case AARCH64_OPND_SVE_ADDR_RI_S4x4xVL:
1703 min_value = -8;
1704 max_value = 7;
1705 sve_imm_offset_vl:
1706 assert (!opnd->addr.offset.is_reg);
1707 assert (opnd->addr.preind);
1708 num = 1 + get_operand_specific_data (&aarch64_operands[type]);
1709 min_value *= num;
1710 max_value *= num;
1711 if ((opnd->addr.offset.imm != 0 && !opnd->shifter.operator_present)
1712 || (opnd->shifter.operator_present
1713 && opnd->shifter.kind != AARCH64_MOD_MUL_VL))
1714 {
1715 set_other_error (mismatch_detail, idx,
1716 _("invalid addressing mode"));
1717 return 0;
1718 }
1719 if (!value_in_range_p (opnd->addr.offset.imm, min_value, max_value))
1720 {
1721 set_offset_out_of_range_error (mismatch_detail, idx,
1722 min_value, max_value);
1723 return 0;
1724 }
1725 if (!value_aligned_p (opnd->addr.offset.imm, num))
1726 {
1727 set_unaligned_error (mismatch_detail, idx, num);
1728 return 0;
1729 }
1730 break;
1731
1732 case AARCH64_OPND_SVE_ADDR_RI_S6xVL:
1733 min_value = -32;
1734 max_value = 31;
1735 goto sve_imm_offset_vl;
1736
1737 case AARCH64_OPND_SVE_ADDR_RI_S9xVL:
1738 min_value = -256;
1739 max_value = 255;
1740 goto sve_imm_offset_vl;
1741
4df068de
RS
1742 case AARCH64_OPND_SVE_ADDR_RI_U6:
1743 case AARCH64_OPND_SVE_ADDR_RI_U6x2:
1744 case AARCH64_OPND_SVE_ADDR_RI_U6x4:
1745 case AARCH64_OPND_SVE_ADDR_RI_U6x8:
1746 min_value = 0;
1747 max_value = 63;
1748 sve_imm_offset:
1749 assert (!opnd->addr.offset.is_reg);
1750 assert (opnd->addr.preind);
1751 num = 1 << get_operand_specific_data (&aarch64_operands[type]);
1752 min_value *= num;
1753 max_value *= num;
1754 if (opnd->shifter.operator_present
1755 || opnd->shifter.amount_present)
1756 {
1757 set_other_error (mismatch_detail, idx,
1758 _("invalid addressing mode"));
1759 return 0;
1760 }
1761 if (!value_in_range_p (opnd->addr.offset.imm, min_value, max_value))
1762 {
1763 set_offset_out_of_range_error (mismatch_detail, idx,
1764 min_value, max_value);
1765 return 0;
1766 }
1767 if (!value_aligned_p (opnd->addr.offset.imm, num))
1768 {
1769 set_unaligned_error (mismatch_detail, idx, num);
1770 return 0;
1771 }
1772 break;
1773
1774 case AARCH64_OPND_SVE_ADDR_RR:
1775 case AARCH64_OPND_SVE_ADDR_RR_LSL1:
1776 case AARCH64_OPND_SVE_ADDR_RR_LSL2:
1777 case AARCH64_OPND_SVE_ADDR_RR_LSL3:
1778 case AARCH64_OPND_SVE_ADDR_RX:
1779 case AARCH64_OPND_SVE_ADDR_RX_LSL1:
1780 case AARCH64_OPND_SVE_ADDR_RX_LSL2:
1781 case AARCH64_OPND_SVE_ADDR_RX_LSL3:
1782 case AARCH64_OPND_SVE_ADDR_RZ:
1783 case AARCH64_OPND_SVE_ADDR_RZ_LSL1:
1784 case AARCH64_OPND_SVE_ADDR_RZ_LSL2:
1785 case AARCH64_OPND_SVE_ADDR_RZ_LSL3:
1786 modifiers = 1 << AARCH64_MOD_LSL;
1787 sve_rr_operand:
1788 assert (opnd->addr.offset.is_reg);
1789 assert (opnd->addr.preind);
1790 if ((aarch64_operands[type].flags & OPD_F_NO_ZR) != 0
1791 && opnd->addr.offset.regno == 31)
1792 {
1793 set_other_error (mismatch_detail, idx,
1794 _("index register xzr is not allowed"));
1795 return 0;
1796 }
1797 if (((1 << opnd->shifter.kind) & modifiers) == 0
1798 || (opnd->shifter.amount
1799 != get_operand_specific_data (&aarch64_operands[type])))
1800 {
1801 set_other_error (mismatch_detail, idx,
1802 _("invalid addressing mode"));
1803 return 0;
1804 }
1805 break;
1806
1807 case AARCH64_OPND_SVE_ADDR_RZ_XTW_14:
1808 case AARCH64_OPND_SVE_ADDR_RZ_XTW_22:
1809 case AARCH64_OPND_SVE_ADDR_RZ_XTW1_14:
1810 case AARCH64_OPND_SVE_ADDR_RZ_XTW1_22:
1811 case AARCH64_OPND_SVE_ADDR_RZ_XTW2_14:
1812 case AARCH64_OPND_SVE_ADDR_RZ_XTW2_22:
1813 case AARCH64_OPND_SVE_ADDR_RZ_XTW3_14:
1814 case AARCH64_OPND_SVE_ADDR_RZ_XTW3_22:
1815 modifiers = (1 << AARCH64_MOD_SXTW) | (1 << AARCH64_MOD_UXTW);
1816 goto sve_rr_operand;
1817
1818 case AARCH64_OPND_SVE_ADDR_ZI_U5:
1819 case AARCH64_OPND_SVE_ADDR_ZI_U5x2:
1820 case AARCH64_OPND_SVE_ADDR_ZI_U5x4:
1821 case AARCH64_OPND_SVE_ADDR_ZI_U5x8:
1822 min_value = 0;
1823 max_value = 31;
1824 goto sve_imm_offset;
1825
1826 case AARCH64_OPND_SVE_ADDR_ZZ_LSL:
1827 modifiers = 1 << AARCH64_MOD_LSL;
1828 sve_zz_operand:
1829 assert (opnd->addr.offset.is_reg);
1830 assert (opnd->addr.preind);
1831 if (((1 << opnd->shifter.kind) & modifiers) == 0
1832 || opnd->shifter.amount < 0
1833 || opnd->shifter.amount > 3)
1834 {
1835 set_other_error (mismatch_detail, idx,
1836 _("invalid addressing mode"));
1837 return 0;
1838 }
1839 break;
1840
1841 case AARCH64_OPND_SVE_ADDR_ZZ_SXTW:
1842 modifiers = (1 << AARCH64_MOD_SXTW);
1843 goto sve_zz_operand;
1844
1845 case AARCH64_OPND_SVE_ADDR_ZZ_UXTW:
1846 modifiers = 1 << AARCH64_MOD_UXTW;
1847 goto sve_zz_operand;
1848
a06ea964
NC
1849 default:
1850 break;
1851 }
1852 break;
1853
1854 case AARCH64_OPND_CLASS_SIMD_REGLIST:
dab26bf4
RS
1855 if (type == AARCH64_OPND_LEt)
1856 {
1857 /* Get the upper bound for the element index. */
1858 num = 16 / aarch64_get_qualifier_esize (qualifier) - 1;
1859 if (!value_in_range_p (opnd->reglist.index, 0, num))
1860 {
1861 set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, num);
1862 return 0;
1863 }
1864 }
a06ea964
NC
1865 /* The opcode dependent area stores the number of elements in
1866 each structure to be loaded/stored. */
1867 num = get_opcode_dependent_value (opcode);
1868 switch (type)
1869 {
1870 case AARCH64_OPND_LVt:
1871 assert (num >= 1 && num <= 4);
1872 /* Unless LD1/ST1, the number of registers should be equal to that
1873 of the structure elements. */
1874 if (num != 1 && opnd->reglist.num_regs != num)
1875 {
1876 set_reg_list_error (mismatch_detail, idx, num);
1877 return 0;
1878 }
1879 break;
1880 case AARCH64_OPND_LVt_AL:
1881 case AARCH64_OPND_LEt:
1882 assert (num >= 1 && num <= 4);
1883 /* The number of registers should be equal to that of the structure
1884 elements. */
1885 if (opnd->reglist.num_regs != num)
1886 {
1887 set_reg_list_error (mismatch_detail, idx, num);
1888 return 0;
1889 }
1890 break;
1891 default:
1892 break;
1893 }
1894 break;
1895
1896 case AARCH64_OPND_CLASS_IMMEDIATE:
1897 /* Constraint check on immediate operand. */
1898 imm = opnd->imm.value;
1899 /* E.g. imm_0_31 constrains value to be 0..31. */
1900 if (qualifier_value_in_range_constraint_p (qualifier)
1901 && !value_in_range_p (imm, get_lower_bound (qualifier),
1902 get_upper_bound (qualifier)))
1903 {
1904 set_imm_out_of_range_error (mismatch_detail, idx,
1905 get_lower_bound (qualifier),
1906 get_upper_bound (qualifier));
1907 return 0;
1908 }
1909
1910 switch (type)
1911 {
1912 case AARCH64_OPND_AIMM:
1913 if (opnd->shifter.kind != AARCH64_MOD_LSL)
1914 {
1915 set_other_error (mismatch_detail, idx,
1916 _("invalid shift operator"));
1917 return 0;
1918 }
1919 if (opnd->shifter.amount != 0 && opnd->shifter.amount != 12)
1920 {
1921 set_other_error (mismatch_detail, idx,
ab3b8fcf 1922 _("shift amount must be 0 or 12"));
a06ea964
NC
1923 return 0;
1924 }
1925 if (!value_fit_unsigned_field_p (opnd->imm.value, 12))
1926 {
1927 set_other_error (mismatch_detail, idx,
1928 _("immediate out of range"));
1929 return 0;
1930 }
1931 break;
1932
1933 case AARCH64_OPND_HALF:
1934 assert (idx == 1 && opnds[0].type == AARCH64_OPND_Rd);
1935 if (opnd->shifter.kind != AARCH64_MOD_LSL)
1936 {
1937 set_other_error (mismatch_detail, idx,
1938 _("invalid shift operator"));
1939 return 0;
1940 }
1941 size = aarch64_get_qualifier_esize (opnds[0].qualifier);
1942 if (!value_aligned_p (opnd->shifter.amount, 16))
1943 {
1944 set_other_error (mismatch_detail, idx,
ab3b8fcf 1945 _("shift amount must be a multiple of 16"));
a06ea964
NC
1946 return 0;
1947 }
1948 if (!value_in_range_p (opnd->shifter.amount, 0, size * 8 - 16))
1949 {
1950 set_sft_amount_out_of_range_error (mismatch_detail, idx,
1951 0, size * 8 - 16);
1952 return 0;
1953 }
1954 if (opnd->imm.value < 0)
1955 {
1956 set_other_error (mismatch_detail, idx,
1957 _("negative immediate value not allowed"));
1958 return 0;
1959 }
1960 if (!value_fit_unsigned_field_p (opnd->imm.value, 16))
1961 {
1962 set_other_error (mismatch_detail, idx,
1963 _("immediate out of range"));
1964 return 0;
1965 }
1966 break;
1967
1968 case AARCH64_OPND_IMM_MOV:
1969 {
42408347 1970 int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
a06ea964
NC
1971 imm = opnd->imm.value;
1972 assert (idx == 1);
1973 switch (opcode->op)
1974 {
1975 case OP_MOV_IMM_WIDEN:
1976 imm = ~imm;
1a0670f3 1977 /* Fall through. */
a06ea964 1978 case OP_MOV_IMM_WIDE:
42408347 1979 if (!aarch64_wide_constant_p (imm, esize == 4, NULL))
a06ea964
NC
1980 {
1981 set_other_error (mismatch_detail, idx,
1982 _("immediate out of range"));
1983 return 0;
1984 }
1985 break;
1986 case OP_MOV_IMM_LOG:
42408347 1987 if (!aarch64_logical_immediate_p (imm, esize, NULL))
a06ea964
NC
1988 {
1989 set_other_error (mismatch_detail, idx,
1990 _("immediate out of range"));
1991 return 0;
1992 }
1993 break;
1994 default:
1995 assert (0);
1996 return 0;
1997 }
1998 }
1999 break;
2000
2001 case AARCH64_OPND_NZCV:
2002 case AARCH64_OPND_CCMP_IMM:
2003 case AARCH64_OPND_EXCEPTION:
2004 case AARCH64_OPND_UIMM4:
2005 case AARCH64_OPND_UIMM7:
2006 case AARCH64_OPND_UIMM3_OP1:
2007 case AARCH64_OPND_UIMM3_OP2:
e950b345
RS
2008 case AARCH64_OPND_SVE_UIMM3:
2009 case AARCH64_OPND_SVE_UIMM7:
2010 case AARCH64_OPND_SVE_UIMM8:
2011 case AARCH64_OPND_SVE_UIMM8_53:
a06ea964
NC
2012 size = get_operand_fields_width (get_operand_from_code (type));
2013 assert (size < 32);
2014 if (!value_fit_unsigned_field_p (opnd->imm.value, size))
2015 {
2016 set_imm_out_of_range_error (mismatch_detail, idx, 0,
2017 (1 << size) - 1);
2018 return 0;
2019 }
2020 break;
2021
e950b345
RS
2022 case AARCH64_OPND_SIMM5:
2023 case AARCH64_OPND_SVE_SIMM5:
2024 case AARCH64_OPND_SVE_SIMM5B:
2025 case AARCH64_OPND_SVE_SIMM6:
2026 case AARCH64_OPND_SVE_SIMM8:
2027 size = get_operand_fields_width (get_operand_from_code (type));
2028 assert (size < 32);
2029 if (!value_fit_signed_field_p (opnd->imm.value, size))
2030 {
2031 set_imm_out_of_range_error (mismatch_detail, idx,
2032 -(1 << (size - 1)),
2033 (1 << (size - 1)) - 1);
2034 return 0;
2035 }
2036 break;
2037
a06ea964 2038 case AARCH64_OPND_WIDTH:
d685192a 2039 assert (idx > 1 && opnds[idx-1].type == AARCH64_OPND_IMM
a06ea964
NC
2040 && opnds[0].type == AARCH64_OPND_Rd);
2041 size = get_upper_bound (qualifier);
2042 if (opnd->imm.value + opnds[idx-1].imm.value > size)
2043 /* lsb+width <= reg.size */
2044 {
2045 set_imm_out_of_range_error (mismatch_detail, idx, 1,
2046 size - opnds[idx-1].imm.value);
2047 return 0;
2048 }
2049 break;
2050
2051 case AARCH64_OPND_LIMM:
e950b345 2052 case AARCH64_OPND_SVE_LIMM:
42408347
RS
2053 {
2054 int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
2055 uint64_t uimm = opnd->imm.value;
2056 if (opcode->op == OP_BIC)
2057 uimm = ~uimm;
2058 if (aarch64_logical_immediate_p (uimm, esize, NULL) == FALSE)
2059 {
2060 set_other_error (mismatch_detail, idx,
2061 _("immediate out of range"));
2062 return 0;
2063 }
2064 }
a06ea964
NC
2065 break;
2066
2067 case AARCH64_OPND_IMM0:
2068 case AARCH64_OPND_FPIMM0:
2069 if (opnd->imm.value != 0)
2070 {
2071 set_other_error (mismatch_detail, idx,
2072 _("immediate zero expected"));
2073 return 0;
2074 }
2075 break;
2076
2077 case AARCH64_OPND_SHLL_IMM:
2078 assert (idx == 2);
2079 size = 8 * aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
2080 if (opnd->imm.value != size)
2081 {
2082 set_other_error (mismatch_detail, idx,
2083 _("invalid shift amount"));
2084 return 0;
2085 }
2086 break;
2087
2088 case AARCH64_OPND_IMM_VLSL:
2089 size = aarch64_get_qualifier_esize (qualifier);
2090 if (!value_in_range_p (opnd->imm.value, 0, size * 8 - 1))
2091 {
2092 set_imm_out_of_range_error (mismatch_detail, idx, 0,
2093 size * 8 - 1);
2094 return 0;
2095 }
2096 break;
2097
2098 case AARCH64_OPND_IMM_VLSR:
2099 size = aarch64_get_qualifier_esize (qualifier);
2100 if (!value_in_range_p (opnd->imm.value, 1, size * 8))
2101 {
2102 set_imm_out_of_range_error (mismatch_detail, idx, 1, size * 8);
2103 return 0;
2104 }
2105 break;
2106
2107 case AARCH64_OPND_SIMD_IMM:
2108 case AARCH64_OPND_SIMD_IMM_SFT:
2109 /* Qualifier check. */
2110 switch (qualifier)
2111 {
2112 case AARCH64_OPND_QLF_LSL:
2113 if (opnd->shifter.kind != AARCH64_MOD_LSL)
2114 {
2115 set_other_error (mismatch_detail, idx,
2116 _("invalid shift operator"));
2117 return 0;
2118 }
2119 break;
2120 case AARCH64_OPND_QLF_MSL:
2121 if (opnd->shifter.kind != AARCH64_MOD_MSL)
2122 {
2123 set_other_error (mismatch_detail, idx,
2124 _("invalid shift operator"));
2125 return 0;
2126 }
2127 break;
2128 case AARCH64_OPND_QLF_NIL:
2129 if (opnd->shifter.kind != AARCH64_MOD_NONE)
2130 {
2131 set_other_error (mismatch_detail, idx,
2132 _("shift is not permitted"));
2133 return 0;
2134 }
2135 break;
2136 default:
2137 assert (0);
2138 return 0;
2139 }
2140 /* Is the immediate valid? */
2141 assert (idx == 1);
2142 if (aarch64_get_qualifier_esize (opnds[0].qualifier) != 8)
2143 {
d2865ed3
YZ
2144 /* uimm8 or simm8 */
2145 if (!value_in_range_p (opnd->imm.value, -128, 255))
a06ea964 2146 {
d2865ed3 2147 set_imm_out_of_range_error (mismatch_detail, idx, -128, 255);
a06ea964
NC
2148 return 0;
2149 }
2150 }
2151 else if (aarch64_shrink_expanded_imm8 (opnd->imm.value) < 0)
2152 {
2153 /* uimm64 is not
2154 'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeee
2155 ffffffffgggggggghhhhhhhh'. */
2156 set_other_error (mismatch_detail, idx,
2157 _("invalid value for immediate"));
2158 return 0;
2159 }
2160 /* Is the shift amount valid? */
2161 switch (opnd->shifter.kind)
2162 {
2163 case AARCH64_MOD_LSL:
2164 size = aarch64_get_qualifier_esize (opnds[0].qualifier);
f5555712 2165 if (!value_in_range_p (opnd->shifter.amount, 0, (size - 1) * 8))
a06ea964 2166 {
f5555712
YZ
2167 set_sft_amount_out_of_range_error (mismatch_detail, idx, 0,
2168 (size - 1) * 8);
a06ea964
NC
2169 return 0;
2170 }
f5555712 2171 if (!value_aligned_p (opnd->shifter.amount, 8))
a06ea964 2172 {
f5555712 2173 set_unaligned_error (mismatch_detail, idx, 8);
a06ea964
NC
2174 return 0;
2175 }
2176 break;
2177 case AARCH64_MOD_MSL:
2178 /* Only 8 and 16 are valid shift amount. */
2179 if (opnd->shifter.amount != 8 && opnd->shifter.amount != 16)
2180 {
2181 set_other_error (mismatch_detail, idx,
ab3b8fcf 2182 _("shift amount must be 0 or 16"));
a06ea964
NC
2183 return 0;
2184 }
2185 break;
2186 default:
2187 if (opnd->shifter.kind != AARCH64_MOD_NONE)
2188 {
2189 set_other_error (mismatch_detail, idx,
2190 _("invalid shift operator"));
2191 return 0;
2192 }
2193 break;
2194 }
2195 break;
2196
2197 case AARCH64_OPND_FPIMM:
2198 case AARCH64_OPND_SIMD_FPIMM:
165d4950 2199 case AARCH64_OPND_SVE_FPIMM8:
a06ea964
NC
2200 if (opnd->imm.is_fp == 0)
2201 {
2202 set_other_error (mismatch_detail, idx,
2203 _("floating-point immediate expected"));
2204 return 0;
2205 }
2206 /* The value is expected to be an 8-bit floating-point constant with
2207 sign, 3-bit exponent and normalized 4 bits of precision, encoded
2208 in "a:b:c:d:e:f:g:h" or FLD_imm8 (depending on the type of the
2209 instruction). */
2210 if (!value_in_range_p (opnd->imm.value, 0, 255))
2211 {
2212 set_other_error (mismatch_detail, idx,
2213 _("immediate out of range"));
2214 return 0;
2215 }
2216 if (opnd->shifter.kind != AARCH64_MOD_NONE)
2217 {
2218 set_other_error (mismatch_detail, idx,
2219 _("invalid shift operator"));
2220 return 0;
2221 }
2222 break;
2223
e950b345
RS
2224 case AARCH64_OPND_SVE_AIMM:
2225 min_value = 0;
2226 sve_aimm:
2227 assert (opnd->shifter.kind == AARCH64_MOD_LSL);
2228 size = aarch64_get_qualifier_esize (opnds[0].qualifier);
2229 mask = ~((uint64_t) -1 << (size * 4) << (size * 4));
2230 uvalue = opnd->imm.value;
2231 shift = opnd->shifter.amount;
2232 if (size == 1)
2233 {
2234 if (shift != 0)
2235 {
2236 set_other_error (mismatch_detail, idx,
2237 _("no shift amount allowed for"
2238 " 8-bit constants"));
2239 return 0;
2240 }
2241 }
2242 else
2243 {
2244 if (shift != 0 && shift != 8)
2245 {
2246 set_other_error (mismatch_detail, idx,
2247 _("shift amount must be 0 or 8"));
2248 return 0;
2249 }
2250 if (shift == 0 && (uvalue & 0xff) == 0)
2251 {
2252 shift = 8;
2253 uvalue = (int64_t) uvalue / 256;
2254 }
2255 }
2256 mask >>= shift;
2257 if ((uvalue & mask) != uvalue && (uvalue | ~mask) != uvalue)
2258 {
2259 set_other_error (mismatch_detail, idx,
2260 _("immediate too big for element size"));
2261 return 0;
2262 }
2263 uvalue = (uvalue - min_value) & mask;
2264 if (uvalue > 0xff)
2265 {
2266 set_other_error (mismatch_detail, idx,
2267 _("invalid arithmetic immediate"));
2268 return 0;
2269 }
2270 break;
2271
2272 case AARCH64_OPND_SVE_ASIMM:
2273 min_value = -128;
2274 goto sve_aimm;
2275
165d4950
RS
2276 case AARCH64_OPND_SVE_I1_HALF_ONE:
2277 assert (opnd->imm.is_fp);
2278 if (opnd->imm.value != 0x3f000000 && opnd->imm.value != 0x3f800000)
2279 {
2280 set_other_error (mismatch_detail, idx,
2281 _("floating-point value must be 0.5 or 1.0"));
2282 return 0;
2283 }
2284 break;
2285
2286 case AARCH64_OPND_SVE_I1_HALF_TWO:
2287 assert (opnd->imm.is_fp);
2288 if (opnd->imm.value != 0x3f000000 && opnd->imm.value != 0x40000000)
2289 {
2290 set_other_error (mismatch_detail, idx,
2291 _("floating-point value must be 0.5 or 2.0"));
2292 return 0;
2293 }
2294 break;
2295
2296 case AARCH64_OPND_SVE_I1_ZERO_ONE:
2297 assert (opnd->imm.is_fp);
2298 if (opnd->imm.value != 0 && opnd->imm.value != 0x3f800000)
2299 {
2300 set_other_error (mismatch_detail, idx,
2301 _("floating-point value must be 0.0 or 1.0"));
2302 return 0;
2303 }
2304 break;
2305
e950b345
RS
2306 case AARCH64_OPND_SVE_INV_LIMM:
2307 {
2308 int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
2309 uint64_t uimm = ~opnd->imm.value;
2310 if (!aarch64_logical_immediate_p (uimm, esize, NULL))
2311 {
2312 set_other_error (mismatch_detail, idx,
2313 _("immediate out of range"));
2314 return 0;
2315 }
2316 }
2317 break;
2318
2319 case AARCH64_OPND_SVE_LIMM_MOV:
2320 {
2321 int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
2322 uint64_t uimm = opnd->imm.value;
2323 if (!aarch64_logical_immediate_p (uimm, esize, NULL))
2324 {
2325 set_other_error (mismatch_detail, idx,
2326 _("immediate out of range"));
2327 return 0;
2328 }
2329 if (!aarch64_sve_dupm_mov_immediate_p (uimm, esize))
2330 {
2331 set_other_error (mismatch_detail, idx,
2332 _("invalid replicated MOV immediate"));
2333 return 0;
2334 }
2335 }
2336 break;
2337
2442d846
RS
2338 case AARCH64_OPND_SVE_PATTERN_SCALED:
2339 assert (opnd->shifter.kind == AARCH64_MOD_MUL);
2340 if (!value_in_range_p (opnd->shifter.amount, 1, 16))
2341 {
2342 set_multiplier_out_of_range_error (mismatch_detail, idx, 1, 16);
2343 return 0;
2344 }
2345 break;
2346
e950b345
RS
2347 case AARCH64_OPND_SVE_SHLIMM_PRED:
2348 case AARCH64_OPND_SVE_SHLIMM_UNPRED:
2349 size = aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
2350 if (!value_in_range_p (opnd->imm.value, 0, 8 * size - 1))
2351 {
2352 set_imm_out_of_range_error (mismatch_detail, idx,
2353 0, 8 * size - 1);
2354 return 0;
2355 }
2356 break;
2357
2358 case AARCH64_OPND_SVE_SHRIMM_PRED:
2359 case AARCH64_OPND_SVE_SHRIMM_UNPRED:
2360 size = aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
2361 if (!value_in_range_p (opnd->imm.value, 1, 8 * size))
2362 {
2363 set_imm_out_of_range_error (mismatch_detail, idx, 1, 8 * size);
2364 return 0;
2365 }
2366 break;
2367
a06ea964
NC
2368 default:
2369 break;
2370 }
2371 break;
2372
2373 case AARCH64_OPND_CLASS_CP_REG:
2374 /* Cn or Cm: 4-bit opcode field named for historical reasons.
2375 valid range: C0 - C15. */
2376 if (opnd->reg.regno > 15)
2377 {
2378 set_regno_out_of_range_error (mismatch_detail, idx, 0, 15);
2379 return 0;
2380 }
2381 break;
2382
2383 case AARCH64_OPND_CLASS_SYSTEM:
2384 switch (type)
2385 {
2386 case AARCH64_OPND_PSTATEFIELD:
2387 assert (idx == 0 && opnds[1].type == AARCH64_OPND_UIMM4);
0bff6e2d
MW
2388 /* MSR UAO, #uimm4
2389 MSR PAN, #uimm4
c2825638 2390 The immediate must be #0 or #1. */
0bff6e2d
MW
2391 if ((opnd->pstatefield == 0x03 /* UAO. */
2392 || opnd->pstatefield == 0x04) /* PAN. */
c2825638
MW
2393 && opnds[1].imm.value > 1)
2394 {
2395 set_imm_out_of_range_error (mismatch_detail, idx, 0, 1);
2396 return 0;
2397 }
a06ea964
NC
2398 /* MSR SPSel, #uimm4
2399 Uses uimm4 as a control value to select the stack pointer: if
2400 bit 0 is set it selects the current exception level's stack
2401 pointer, if bit 0 is clear it selects shared EL0 stack pointer.
2402 Bits 1 to 3 of uimm4 are reserved and should be zero. */
2403 if (opnd->pstatefield == 0x05 /* spsel */ && opnds[1].imm.value > 1)
2404 {
2405 set_imm_out_of_range_error (mismatch_detail, idx, 0, 1);
2406 return 0;
2407 }
2408 break;
2409 default:
2410 break;
2411 }
2412 break;
2413
2414 case AARCH64_OPND_CLASS_SIMD_ELEMENT:
2415 /* Get the upper bound for the element index. */
2416 num = 16 / aarch64_get_qualifier_esize (qualifier) - 1;
2417 /* Index out-of-range. */
2418 if (!value_in_range_p (opnd->reglane.index, 0, num))
2419 {
2420 set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, num);
2421 return 0;
2422 }
2423 /* SMLAL<Q> <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>].
2424 <Vm> Is the vector register (V0-V31) or (V0-V15), whose
2425 number is encoded in "size:M:Rm":
2426 size <Vm>
2427 00 RESERVED
2428 01 0:Rm
2429 10 M:Rm
2430 11 RESERVED */
2431 if (type == AARCH64_OPND_Em && qualifier == AARCH64_OPND_QLF_S_H
2432 && !value_in_range_p (opnd->reglane.regno, 0, 15))
2433 {
2434 set_regno_out_of_range_error (mismatch_detail, idx, 0, 15);
2435 return 0;
2436 }
2437 break;
2438
2439 case AARCH64_OPND_CLASS_MODIFIED_REG:
2440 assert (idx == 1 || idx == 2);
2441 switch (type)
2442 {
2443 case AARCH64_OPND_Rm_EXT:
2444 if (aarch64_extend_operator_p (opnd->shifter.kind) == FALSE
2445 && opnd->shifter.kind != AARCH64_MOD_LSL)
2446 {
2447 set_other_error (mismatch_detail, idx,
2448 _("extend operator expected"));
2449 return 0;
2450 }
2451 /* It is not optional unless at least one of "Rd" or "Rn" is '11111'
2452 (i.e. SP), in which case it defaults to LSL. The LSL alias is
2453 only valid when "Rd" or "Rn" is '11111', and is preferred in that
2454 case. */
2455 if (!aarch64_stack_pointer_p (opnds + 0)
2456 && (idx != 2 || !aarch64_stack_pointer_p (opnds + 1)))
2457 {
2458 if (!opnd->shifter.operator_present)
2459 {
2460 set_other_error (mismatch_detail, idx,
2461 _("missing extend operator"));
2462 return 0;
2463 }
2464 else if (opnd->shifter.kind == AARCH64_MOD_LSL)
2465 {
2466 set_other_error (mismatch_detail, idx,
2467 _("'LSL' operator not allowed"));
2468 return 0;
2469 }
2470 }
2471 assert (opnd->shifter.operator_present /* Default to LSL. */
2472 || opnd->shifter.kind == AARCH64_MOD_LSL);
2473 if (!value_in_range_p (opnd->shifter.amount, 0, 4))
2474 {
2475 set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, 4);
2476 return 0;
2477 }
2478 /* In the 64-bit form, the final register operand is written as Wm
2479 for all but the (possibly omitted) UXTX/LSL and SXTX
2480 operators.
2481 N.B. GAS allows X register to be used with any operator as a
2482 programming convenience. */
2483 if (qualifier == AARCH64_OPND_QLF_X
2484 && opnd->shifter.kind != AARCH64_MOD_LSL
2485 && opnd->shifter.kind != AARCH64_MOD_UXTX
2486 && opnd->shifter.kind != AARCH64_MOD_SXTX)
2487 {
2488 set_other_error (mismatch_detail, idx, _("W register expected"));
2489 return 0;
2490 }
2491 break;
2492
2493 case AARCH64_OPND_Rm_SFT:
2494 /* ROR is not available to the shifted register operand in
2495 arithmetic instructions. */
2496 if (aarch64_shift_operator_p (opnd->shifter.kind) == FALSE)
2497 {
2498 set_other_error (mismatch_detail, idx,
2499 _("shift operator expected"));
2500 return 0;
2501 }
2502 if (opnd->shifter.kind == AARCH64_MOD_ROR
2503 && opcode->iclass != log_shift)
2504 {
2505 set_other_error (mismatch_detail, idx,
2506 _("'ROR' operator not allowed"));
2507 return 0;
2508 }
2509 num = qualifier == AARCH64_OPND_QLF_W ? 31 : 63;
2510 if (!value_in_range_p (opnd->shifter.amount, 0, num))
2511 {
2512 set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, num);
2513 return 0;
2514 }
2515 break;
2516
2517 default:
2518 break;
2519 }
2520 break;
2521
2522 default:
2523 break;
2524 }
2525
2526 return 1;
2527}
2528
2529/* Main entrypoint for the operand constraint checking.
2530
2531 Return 1 if operands of *INST meet the constraint applied by the operand
2532 codes and operand qualifiers; otherwise return 0 and if MISMATCH_DETAIL is
2533 not NULL, return the detail of the error in *MISMATCH_DETAIL. N.B. when
2534 adding more constraint checking, make sure MISMATCH_DETAIL->KIND is set
2535 with a proper error kind rather than AARCH64_OPDE_NIL (GAS asserts non-NIL
2536 error kind when it is notified that an instruction does not pass the check).
2537
2538 Un-determined operand qualifiers may get established during the process. */
2539
2540int
2541aarch64_match_operands_constraint (aarch64_inst *inst,
2542 aarch64_operand_error *mismatch_detail)
2543{
2544 int i;
2545
2546 DEBUG_TRACE ("enter");
2547
0c608d6b
RS
2548 /* Check for cases where a source register needs to be the same as the
2549 destination register. Do this before matching qualifiers since if
2550 an instruction has both invalid tying and invalid qualifiers,
2551 the error about qualifiers would suggest several alternative
2552 instructions that also have invalid tying. */
2553 i = inst->opcode->tied_operand;
2554 if (i > 0 && (inst->operands[0].reg.regno != inst->operands[i].reg.regno))
2555 {
2556 if (mismatch_detail)
2557 {
2558 mismatch_detail->kind = AARCH64_OPDE_UNTIED_OPERAND;
2559 mismatch_detail->index = i;
2560 mismatch_detail->error = NULL;
2561 }
2562 return 0;
2563 }
2564
a06ea964
NC
2565 /* Match operands' qualifier.
2566 *INST has already had qualifier establish for some, if not all, of
2567 its operands; we need to find out whether these established
2568 qualifiers match one of the qualifier sequence in
2569 INST->OPCODE->QUALIFIERS_LIST. If yes, we will assign each operand
2570 with the corresponding qualifier in such a sequence.
2571 Only basic operand constraint checking is done here; the more thorough
2572 constraint checking will carried out by operand_general_constraint_met_p,
2573 which has be to called after this in order to get all of the operands'
2574 qualifiers established. */
2575 if (match_operands_qualifier (inst, TRUE /* update_p */) == 0)
2576 {
2577 DEBUG_TRACE ("FAIL on operand qualifier matching");
2578 if (mismatch_detail)
2579 {
2580 /* Return an error type to indicate that it is the qualifier
2581 matching failure; we don't care about which operand as there
2582 are enough information in the opcode table to reproduce it. */
2583 mismatch_detail->kind = AARCH64_OPDE_INVALID_VARIANT;
2584 mismatch_detail->index = -1;
2585 mismatch_detail->error = NULL;
2586 }
2587 return 0;
2588 }
2589
2590 /* Match operands' constraint. */
2591 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2592 {
2593 enum aarch64_opnd type = inst->opcode->operands[i];
2594 if (type == AARCH64_OPND_NIL)
2595 break;
2596 if (inst->operands[i].skip)
2597 {
2598 DEBUG_TRACE ("skip the incomplete operand %d", i);
2599 continue;
2600 }
2601 if (operand_general_constraint_met_p (inst->operands, i, type,
2602 inst->opcode, mismatch_detail) == 0)
2603 {
2604 DEBUG_TRACE ("FAIL on operand %d", i);
2605 return 0;
2606 }
2607 }
2608
2609 DEBUG_TRACE ("PASS");
2610
2611 return 1;
2612}
2613
2614/* Replace INST->OPCODE with OPCODE and return the replaced OPCODE.
2615 Also updates the TYPE of each INST->OPERANDS with the corresponding
2616 value of OPCODE->OPERANDS.
2617
2618 Note that some operand qualifiers may need to be manually cleared by
2619 the caller before it further calls the aarch64_opcode_encode; by
2620 doing this, it helps the qualifier matching facilities work
2621 properly. */
2622
2623const aarch64_opcode*
2624aarch64_replace_opcode (aarch64_inst *inst, const aarch64_opcode *opcode)
2625{
2626 int i;
2627 const aarch64_opcode *old = inst->opcode;
2628
2629 inst->opcode = opcode;
2630
2631 /* Update the operand types. */
2632 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2633 {
2634 inst->operands[i].type = opcode->operands[i];
2635 if (opcode->operands[i] == AARCH64_OPND_NIL)
2636 break;
2637 }
2638
2639 DEBUG_TRACE ("replace %s with %s", old->name, opcode->name);
2640
2641 return old;
2642}
2643
2644int
2645aarch64_operand_index (const enum aarch64_opnd *operands, enum aarch64_opnd operand)
2646{
2647 int i;
2648 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2649 if (operands[i] == operand)
2650 return i;
2651 else if (operands[i] == AARCH64_OPND_NIL)
2652 break;
2653 return -1;
2654}
2655\f
72e9f319
RS
2656/* R0...R30, followed by FOR31. */
2657#define BANK(R, FOR31) \
2658 { R (0), R (1), R (2), R (3), R (4), R (5), R (6), R (7), \
2659 R (8), R (9), R (10), R (11), R (12), R (13), R (14), R (15), \
2660 R (16), R (17), R (18), R (19), R (20), R (21), R (22), R (23), \
2661 R (24), R (25), R (26), R (27), R (28), R (29), R (30), FOR31 }
a06ea964
NC
2662/* [0][0] 32-bit integer regs with sp Wn
2663 [0][1] 64-bit integer regs with sp Xn sf=1
2664 [1][0] 32-bit integer regs with #0 Wn
2665 [1][1] 64-bit integer regs with #0 Xn sf=1 */
2666static const char *int_reg[2][2][32] = {
72e9f319
RS
2667#define R32(X) "w" #X
2668#define R64(X) "x" #X
2669 { BANK (R32, "wsp"), BANK (R64, "sp") },
2670 { BANK (R32, "wzr"), BANK (R64, "xzr") }
a06ea964
NC
2671#undef R64
2672#undef R32
2673};
4df068de
RS
2674
2675/* Names of the SVE vector registers, first with .S suffixes,
2676 then with .D suffixes. */
2677
2678static const char *sve_reg[2][32] = {
2679#define ZS(X) "z" #X ".s"
2680#define ZD(X) "z" #X ".d"
2681 BANK (ZS, ZS (31)), BANK (ZD, ZD (31))
2682#undef ZD
2683#undef ZS
2684};
72e9f319 2685#undef BANK
a06ea964
NC
2686
2687/* Return the integer register name.
2688 if SP_REG_P is not 0, R31 is an SP reg, other R31 is the zero reg. */
2689
2690static inline const char *
2691get_int_reg_name (int regno, aarch64_opnd_qualifier_t qualifier, int sp_reg_p)
2692{
2693 const int has_zr = sp_reg_p ? 0 : 1;
2694 const int is_64 = aarch64_get_qualifier_esize (qualifier) == 4 ? 0 : 1;
2695 return int_reg[has_zr][is_64][regno];
2696}
2697
2698/* Like get_int_reg_name, but IS_64 is always 1. */
2699
2700static inline const char *
2701get_64bit_int_reg_name (int regno, int sp_reg_p)
2702{
2703 const int has_zr = sp_reg_p ? 0 : 1;
2704 return int_reg[has_zr][1][regno];
2705}
2706
01dbfe4c
RS
2707/* Get the name of the integer offset register in OPND, using the shift type
2708 to decide whether it's a word or doubleword. */
2709
2710static inline const char *
2711get_offset_int_reg_name (const aarch64_opnd_info *opnd)
2712{
2713 switch (opnd->shifter.kind)
2714 {
2715 case AARCH64_MOD_UXTW:
2716 case AARCH64_MOD_SXTW:
2717 return get_int_reg_name (opnd->addr.offset.regno, AARCH64_OPND_QLF_W, 0);
2718
2719 case AARCH64_MOD_LSL:
2720 case AARCH64_MOD_SXTX:
2721 return get_int_reg_name (opnd->addr.offset.regno, AARCH64_OPND_QLF_X, 0);
2722
2723 default:
2724 abort ();
2725 }
2726}
2727
4df068de
RS
2728/* Get the name of the SVE vector offset register in OPND, using the operand
2729 qualifier to decide whether the suffix should be .S or .D. */
2730
2731static inline const char *
2732get_addr_sve_reg_name (int regno, aarch64_opnd_qualifier_t qualifier)
2733{
2734 assert (qualifier == AARCH64_OPND_QLF_S_S
2735 || qualifier == AARCH64_OPND_QLF_S_D);
2736 return sve_reg[qualifier == AARCH64_OPND_QLF_S_D][regno];
2737}
2738
a06ea964
NC
2739/* Types for expanding an encoded 8-bit value to a floating-point value. */
2740
2741typedef union
2742{
2743 uint64_t i;
2744 double d;
2745} double_conv_t;
2746
2747typedef union
2748{
2749 uint32_t i;
2750 float f;
2751} single_conv_t;
2752
cf86120b
MW
2753typedef union
2754{
2755 uint32_t i;
2756 float f;
2757} half_conv_t;
2758
a06ea964
NC
2759/* IMM8 is an 8-bit floating-point constant with sign, 3-bit exponent and
2760 normalized 4 bits of precision, encoded in "a:b:c:d:e:f:g:h" or FLD_imm8
2761 (depending on the type of the instruction). IMM8 will be expanded to a
cf86120b
MW
2762 single-precision floating-point value (SIZE == 4) or a double-precision
2763 floating-point value (SIZE == 8). A half-precision floating-point value
2764 (SIZE == 2) is expanded to a single-precision floating-point value. The
2765 expanded value is returned. */
a06ea964
NC
2766
2767static uint64_t
cf86120b 2768expand_fp_imm (int size, uint32_t imm8)
a06ea964
NC
2769{
2770 uint64_t imm;
2771 uint32_t imm8_7, imm8_6_0, imm8_6, imm8_6_repl4;
2772
2773 imm8_7 = (imm8 >> 7) & 0x01; /* imm8<7> */
2774 imm8_6_0 = imm8 & 0x7f; /* imm8<6:0> */
2775 imm8_6 = imm8_6_0 >> 6; /* imm8<6> */
2776 imm8_6_repl4 = (imm8_6 << 3) | (imm8_6 << 2)
2777 | (imm8_6 << 1) | imm8_6; /* Replicate(imm8<6>,4) */
cf86120b 2778 if (size == 8)
a06ea964
NC
2779 {
2780 imm = (imm8_7 << (63-32)) /* imm8<7> */
2781 | ((imm8_6 ^ 1) << (62-32)) /* NOT(imm8<6) */
2782 | (imm8_6_repl4 << (58-32)) | (imm8_6 << (57-32))
2783 | (imm8_6 << (56-32)) | (imm8_6 << (55-32)) /* Replicate(imm8<6>,7) */
2784 | (imm8_6_0 << (48-32)); /* imm8<6>:imm8<5:0> */
2785 imm <<= 32;
2786 }
cf86120b 2787 else if (size == 4 || size == 2)
a06ea964
NC
2788 {
2789 imm = (imm8_7 << 31) /* imm8<7> */
2790 | ((imm8_6 ^ 1) << 30) /* NOT(imm8<6>) */
2791 | (imm8_6_repl4 << 26) /* Replicate(imm8<6>,4) */
2792 | (imm8_6_0 << 19); /* imm8<6>:imm8<5:0> */
2793 }
cf86120b
MW
2794 else
2795 {
2796 /* An unsupported size. */
2797 assert (0);
2798 }
a06ea964
NC
2799
2800 return imm;
2801}
2802
2803/* Produce the string representation of the register list operand *OPND
8a7f0c1b
RS
2804 in the buffer pointed by BUF of size SIZE. PREFIX is the part of
2805 the register name that comes before the register number, such as "v". */
a06ea964 2806static void
8a7f0c1b
RS
2807print_register_list (char *buf, size_t size, const aarch64_opnd_info *opnd,
2808 const char *prefix)
a06ea964
NC
2809{
2810 const int num_regs = opnd->reglist.num_regs;
2811 const int first_reg = opnd->reglist.first_regno;
2812 const int last_reg = (first_reg + num_regs - 1) & 0x1f;
2813 const char *qlf_name = aarch64_get_qualifier_name (opnd->qualifier);
2814 char tb[8]; /* Temporary buffer. */
2815
2816 assert (opnd->type != AARCH64_OPND_LEt || opnd->reglist.has_index);
2817 assert (num_regs >= 1 && num_regs <= 4);
2818
2819 /* Prepare the index if any. */
2820 if (opnd->reglist.has_index)
dab26bf4 2821 snprintf (tb, 8, "[%" PRIi64 "]", opnd->reglist.index);
a06ea964
NC
2822 else
2823 tb[0] = '\0';
2824
2825 /* The hyphenated form is preferred for disassembly if there are
2826 more than two registers in the list, and the register numbers
2827 are monotonically increasing in increments of one. */
2828 if (num_regs > 2 && last_reg > first_reg)
8a7f0c1b
RS
2829 snprintf (buf, size, "{%s%d.%s-%s%d.%s}%s", prefix, first_reg, qlf_name,
2830 prefix, last_reg, qlf_name, tb);
a06ea964
NC
2831 else
2832 {
2833 const int reg0 = first_reg;
2834 const int reg1 = (first_reg + 1) & 0x1f;
2835 const int reg2 = (first_reg + 2) & 0x1f;
2836 const int reg3 = (first_reg + 3) & 0x1f;
2837
2838 switch (num_regs)
2839 {
2840 case 1:
8a7f0c1b 2841 snprintf (buf, size, "{%s%d.%s}%s", prefix, reg0, qlf_name, tb);
a06ea964
NC
2842 break;
2843 case 2:
8a7f0c1b
RS
2844 snprintf (buf, size, "{%s%d.%s, %s%d.%s}%s", prefix, reg0, qlf_name,
2845 prefix, reg1, qlf_name, tb);
a06ea964
NC
2846 break;
2847 case 3:
8a7f0c1b
RS
2848 snprintf (buf, size, "{%s%d.%s, %s%d.%s, %s%d.%s}%s",
2849 prefix, reg0, qlf_name, prefix, reg1, qlf_name,
2850 prefix, reg2, qlf_name, tb);
a06ea964
NC
2851 break;
2852 case 4:
8a7f0c1b
RS
2853 snprintf (buf, size, "{%s%d.%s, %s%d.%s, %s%d.%s, %s%d.%s}%s",
2854 prefix, reg0, qlf_name, prefix, reg1, qlf_name,
2855 prefix, reg2, qlf_name, prefix, reg3, qlf_name, tb);
a06ea964
NC
2856 break;
2857 }
2858 }
2859}
2860
01dbfe4c
RS
2861/* Print the register+immediate address in OPND to BUF, which has SIZE
2862 characters. BASE is the name of the base register. */
2863
2864static void
2865print_immediate_offset_address (char *buf, size_t size,
2866 const aarch64_opnd_info *opnd,
2867 const char *base)
2868{
2869 if (opnd->addr.writeback)
2870 {
2871 if (opnd->addr.preind)
ad43e107 2872 snprintf (buf, size, "[%s, #%d]!", base, opnd->addr.offset.imm);
01dbfe4c 2873 else
ad43e107 2874 snprintf (buf, size, "[%s], #%d", base, opnd->addr.offset.imm);
01dbfe4c
RS
2875 }
2876 else
2877 {
98907a70
RS
2878 if (opnd->shifter.operator_present)
2879 {
2880 assert (opnd->shifter.kind == AARCH64_MOD_MUL_VL);
ad43e107 2881 snprintf (buf, size, "[%s, #%d, mul vl]",
98907a70
RS
2882 base, opnd->addr.offset.imm);
2883 }
2884 else if (opnd->addr.offset.imm)
ad43e107 2885 snprintf (buf, size, "[%s, #%d]", base, opnd->addr.offset.imm);
01dbfe4c
RS
2886 else
2887 snprintf (buf, size, "[%s]", base);
2888 }
2889}
2890
a06ea964 2891/* Produce the string representation of the register offset address operand
01dbfe4c
RS
2892 *OPND in the buffer pointed by BUF of size SIZE. BASE and OFFSET are
2893 the names of the base and offset registers. */
a06ea964
NC
2894static void
2895print_register_offset_address (char *buf, size_t size,
01dbfe4c
RS
2896 const aarch64_opnd_info *opnd,
2897 const char *base, const char *offset)
a06ea964 2898{
0d2f91fe 2899 char tb[16]; /* Temporary buffer. */
a06ea964
NC
2900 bfd_boolean print_extend_p = TRUE;
2901 bfd_boolean print_amount_p = TRUE;
2902 const char *shift_name = aarch64_operand_modifiers[opnd->shifter.kind].name;
2903
a06ea964
NC
2904 if (!opnd->shifter.amount && (opnd->qualifier != AARCH64_OPND_QLF_S_B
2905 || !opnd->shifter.amount_present))
2906 {
2907 /* Not print the shift/extend amount when the amount is zero and
2908 when it is not the special case of 8-bit load/store instruction. */
2909 print_amount_p = FALSE;
2910 /* Likewise, no need to print the shift operator LSL in such a
2911 situation. */
01dbfe4c 2912 if (opnd->shifter.kind == AARCH64_MOD_LSL)
a06ea964
NC
2913 print_extend_p = FALSE;
2914 }
2915
2916 /* Prepare for the extend/shift. */
2917 if (print_extend_p)
2918 {
2919 if (print_amount_p)
ad43e107 2920 snprintf (tb, sizeof (tb), ", %s #%" PRIi64, shift_name,
2442d846 2921 opnd->shifter.amount);
a06ea964 2922 else
ad43e107 2923 snprintf (tb, sizeof (tb), ", %s", shift_name);
a06ea964
NC
2924 }
2925 else
2926 tb[0] = '\0';
2927
ad43e107 2928 snprintf (buf, size, "[%s, %s%s]", base, offset, tb);
a06ea964
NC
2929}
2930
2931/* Generate the string representation of the operand OPNDS[IDX] for OPCODE
2932 in *BUF. The caller should pass in the maximum size of *BUF in SIZE.
2933 PC, PCREL_P and ADDRESS are used to pass in and return information about
2934 the PC-relative address calculation, where the PC value is passed in
2935 PC. If the operand is pc-relative related, *PCREL_P (if PCREL_P non-NULL)
2936 will return 1 and *ADDRESS (if ADDRESS non-NULL) will return the
2937 calculated address; otherwise, *PCREL_P (if PCREL_P non-NULL) returns 0.
2938
2939 The function serves both the disassembler and the assembler diagnostics
2940 issuer, which is the reason why it lives in this file. */
2941
2942void
2943aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
2944 const aarch64_opcode *opcode,
2945 const aarch64_opnd_info *opnds, int idx, int *pcrel_p,
2946 bfd_vma *address)
2947{
bb7eff52 2948 unsigned int i, num_conds;
a06ea964
NC
2949 const char *name = NULL;
2950 const aarch64_opnd_info *opnd = opnds + idx;
2951 enum aarch64_modifier_kind kind;
245d2e3f 2952 uint64_t addr, enum_value;
a06ea964
NC
2953
2954 buf[0] = '\0';
2955 if (pcrel_p)
2956 *pcrel_p = 0;
2957
2958 switch (opnd->type)
2959 {
2960 case AARCH64_OPND_Rd:
2961 case AARCH64_OPND_Rn:
2962 case AARCH64_OPND_Rm:
2963 case AARCH64_OPND_Rt:
2964 case AARCH64_OPND_Rt2:
2965 case AARCH64_OPND_Rs:
2966 case AARCH64_OPND_Ra:
2967 case AARCH64_OPND_Rt_SYS:
ee804238 2968 case AARCH64_OPND_PAIRREG:
047cd301 2969 case AARCH64_OPND_SVE_Rm:
a06ea964
NC
2970 /* The optional-ness of <Xt> in e.g. IC <ic_op>{, <Xt>} is determined by
2971 the <ic_op>, therefore we we use opnd->present to override the
2972 generic optional-ness information. */
362c0c4d
JW
2973 if (opnd->type == AARCH64_OPND_Rt_SYS)
2974 {
2975 if (!opnd->present)
2976 break;
2977 }
a06ea964 2978 /* Omit the operand, e.g. RET. */
362c0c4d
JW
2979 else if (optional_operand_p (opcode, idx)
2980 && (opnd->reg.regno
2981 == get_optional_operand_default_value (opcode)))
a06ea964
NC
2982 break;
2983 assert (opnd->qualifier == AARCH64_OPND_QLF_W
2984 || opnd->qualifier == AARCH64_OPND_QLF_X);
2985 snprintf (buf, size, "%s",
2986 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
2987 break;
2988
2989 case AARCH64_OPND_Rd_SP:
2990 case AARCH64_OPND_Rn_SP:
047cd301 2991 case AARCH64_OPND_SVE_Rn_SP:
c84364ec 2992 case AARCH64_OPND_Rm_SP:
a06ea964
NC
2993 assert (opnd->qualifier == AARCH64_OPND_QLF_W
2994 || opnd->qualifier == AARCH64_OPND_QLF_WSP
2995 || opnd->qualifier == AARCH64_OPND_QLF_X
2996 || opnd->qualifier == AARCH64_OPND_QLF_SP);
2997 snprintf (buf, size, "%s",
2998 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 1));
2999 break;
3000
3001 case AARCH64_OPND_Rm_EXT:
3002 kind = opnd->shifter.kind;
3003 assert (idx == 1 || idx == 2);
3004 if ((aarch64_stack_pointer_p (opnds)
3005 || (idx == 2 && aarch64_stack_pointer_p (opnds + 1)))
3006 && ((opnd->qualifier == AARCH64_OPND_QLF_W
3007 && opnds[0].qualifier == AARCH64_OPND_QLF_W
3008 && kind == AARCH64_MOD_UXTW)
3009 || (opnd->qualifier == AARCH64_OPND_QLF_X
3010 && kind == AARCH64_MOD_UXTX)))
3011 {
3012 /* 'LSL' is the preferred form in this case. */
3013 kind = AARCH64_MOD_LSL;
3014 if (opnd->shifter.amount == 0)
3015 {
3016 /* Shifter omitted. */
3017 snprintf (buf, size, "%s",
3018 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
3019 break;
3020 }
3021 }
3022 if (opnd->shifter.amount)
2442d846 3023 snprintf (buf, size, "%s, %s #%" PRIi64,
a06ea964
NC
3024 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
3025 aarch64_operand_modifiers[kind].name,
3026 opnd->shifter.amount);
3027 else
3028 snprintf (buf, size, "%s, %s",
3029 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
3030 aarch64_operand_modifiers[kind].name);
3031 break;
3032
3033 case AARCH64_OPND_Rm_SFT:
3034 assert (opnd->qualifier == AARCH64_OPND_QLF_W
3035 || opnd->qualifier == AARCH64_OPND_QLF_X);
3036 if (opnd->shifter.amount == 0 && opnd->shifter.kind == AARCH64_MOD_LSL)
3037 snprintf (buf, size, "%s",
3038 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
3039 else
2442d846 3040 snprintf (buf, size, "%s, %s #%" PRIi64,
a06ea964
NC
3041 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
3042 aarch64_operand_modifiers[opnd->shifter.kind].name,
3043 opnd->shifter.amount);
3044 break;
3045
3046 case AARCH64_OPND_Fd:
3047 case AARCH64_OPND_Fn:
3048 case AARCH64_OPND_Fm:
3049 case AARCH64_OPND_Fa:
3050 case AARCH64_OPND_Ft:
3051 case AARCH64_OPND_Ft2:
3052 case AARCH64_OPND_Sd:
3053 case AARCH64_OPND_Sn:
3054 case AARCH64_OPND_Sm:
047cd301
RS
3055 case AARCH64_OPND_SVE_VZn:
3056 case AARCH64_OPND_SVE_Vd:
3057 case AARCH64_OPND_SVE_Vm:
3058 case AARCH64_OPND_SVE_Vn:
a06ea964
NC
3059 snprintf (buf, size, "%s%d", aarch64_get_qualifier_name (opnd->qualifier),
3060 opnd->reg.regno);
3061 break;
3062
3063 case AARCH64_OPND_Vd:
3064 case AARCH64_OPND_Vn:
3065 case AARCH64_OPND_Vm:
3066 snprintf (buf, size, "v%d.%s", opnd->reg.regno,
3067 aarch64_get_qualifier_name (opnd->qualifier));
3068 break;
3069
3070 case AARCH64_OPND_Ed:
3071 case AARCH64_OPND_En:
3072 case AARCH64_OPND_Em:
dab26bf4 3073 snprintf (buf, size, "v%d.%s[%" PRIi64 "]", opnd->reglane.regno,
a06ea964
NC
3074 aarch64_get_qualifier_name (opnd->qualifier),
3075 opnd->reglane.index);
3076 break;
3077
3078 case AARCH64_OPND_VdD1:
3079 case AARCH64_OPND_VnD1:
3080 snprintf (buf, size, "v%d.d[1]", opnd->reg.regno);
3081 break;
3082
3083 case AARCH64_OPND_LVn:
3084 case AARCH64_OPND_LVt:
3085 case AARCH64_OPND_LVt_AL:
3086 case AARCH64_OPND_LEt:
8a7f0c1b 3087 print_register_list (buf, size, opnd, "v");
a06ea964
NC
3088 break;
3089
f11ad6bc
RS
3090 case AARCH64_OPND_SVE_Pd:
3091 case AARCH64_OPND_SVE_Pg3:
3092 case AARCH64_OPND_SVE_Pg4_5:
3093 case AARCH64_OPND_SVE_Pg4_10:
3094 case AARCH64_OPND_SVE_Pg4_16:
3095 case AARCH64_OPND_SVE_Pm:
3096 case AARCH64_OPND_SVE_Pn:
3097 case AARCH64_OPND_SVE_Pt:
3098 if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
3099 snprintf (buf, size, "p%d", opnd->reg.regno);
d50c751e
RS
3100 else if (opnd->qualifier == AARCH64_OPND_QLF_P_Z
3101 || opnd->qualifier == AARCH64_OPND_QLF_P_M)
3102 snprintf (buf, size, "p%d/%s", opnd->reg.regno,
3103 aarch64_get_qualifier_name (opnd->qualifier));
f11ad6bc
RS
3104 else
3105 snprintf (buf, size, "p%d.%s", opnd->reg.regno,
3106 aarch64_get_qualifier_name (opnd->qualifier));
3107 break;
3108
3109 case AARCH64_OPND_SVE_Za_5:
3110 case AARCH64_OPND_SVE_Za_16:
3111 case AARCH64_OPND_SVE_Zd:
3112 case AARCH64_OPND_SVE_Zm_5:
3113 case AARCH64_OPND_SVE_Zm_16:
3114 case AARCH64_OPND_SVE_Zn:
3115 case AARCH64_OPND_SVE_Zt:
3116 if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
3117 snprintf (buf, size, "z%d", opnd->reg.regno);
3118 else
3119 snprintf (buf, size, "z%d.%s", opnd->reg.regno,
3120 aarch64_get_qualifier_name (opnd->qualifier));
3121 break;
3122
3123 case AARCH64_OPND_SVE_ZnxN:
3124 case AARCH64_OPND_SVE_ZtxN:
3125 print_register_list (buf, size, opnd, "z");
3126 break;
3127
3128 case AARCH64_OPND_SVE_Zn_INDEX:
3129 snprintf (buf, size, "z%d.%s[%" PRIi64 "]", opnd->reglane.regno,
3130 aarch64_get_qualifier_name (opnd->qualifier),
3131 opnd->reglane.index);
3132 break;
3133
a06ea964
NC
3134 case AARCH64_OPND_Cn:
3135 case AARCH64_OPND_Cm:
3136 snprintf (buf, size, "C%d", opnd->reg.regno);
3137 break;
3138
3139 case AARCH64_OPND_IDX:
3140 case AARCH64_OPND_IMM:
3141 case AARCH64_OPND_WIDTH:
3142 case AARCH64_OPND_UIMM3_OP1:
3143 case AARCH64_OPND_UIMM3_OP2:
3144 case AARCH64_OPND_BIT_NUM:
3145 case AARCH64_OPND_IMM_VLSL:
3146 case AARCH64_OPND_IMM_VLSR:
3147 case AARCH64_OPND_SHLL_IMM:
3148 case AARCH64_OPND_IMM0:
3149 case AARCH64_OPND_IMMR:
3150 case AARCH64_OPND_IMMS:
3151 case AARCH64_OPND_FBITS:
e950b345
RS
3152 case AARCH64_OPND_SIMM5:
3153 case AARCH64_OPND_SVE_SHLIMM_PRED:
3154 case AARCH64_OPND_SVE_SHLIMM_UNPRED:
3155 case AARCH64_OPND_SVE_SHRIMM_PRED:
3156 case AARCH64_OPND_SVE_SHRIMM_UNPRED:
3157 case AARCH64_OPND_SVE_SIMM5:
3158 case AARCH64_OPND_SVE_SIMM5B:
3159 case AARCH64_OPND_SVE_SIMM6:
3160 case AARCH64_OPND_SVE_SIMM8:
3161 case AARCH64_OPND_SVE_UIMM3:
3162 case AARCH64_OPND_SVE_UIMM7:
3163 case AARCH64_OPND_SVE_UIMM8:
3164 case AARCH64_OPND_SVE_UIMM8_53:
a06ea964
NC
3165 snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
3166 break;
3167
165d4950
RS
3168 case AARCH64_OPND_SVE_I1_HALF_ONE:
3169 case AARCH64_OPND_SVE_I1_HALF_TWO:
3170 case AARCH64_OPND_SVE_I1_ZERO_ONE:
3171 {
3172 single_conv_t c;
3173 c.i = opnd->imm.value;
3174 snprintf (buf, size, "#%.1f", c.f);
3175 break;
3176 }
3177
245d2e3f
RS
3178 case AARCH64_OPND_SVE_PATTERN:
3179 if (optional_operand_p (opcode, idx)
3180 && opnd->imm.value == get_optional_operand_default_value (opcode))
3181 break;
3182 enum_value = opnd->imm.value;
3183 assert (enum_value < ARRAY_SIZE (aarch64_sve_pattern_array));
3184 if (aarch64_sve_pattern_array[enum_value])
3185 snprintf (buf, size, "%s", aarch64_sve_pattern_array[enum_value]);
3186 else
3187 snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
3188 break;
3189
2442d846
RS
3190 case AARCH64_OPND_SVE_PATTERN_SCALED:
3191 if (optional_operand_p (opcode, idx)
3192 && !opnd->shifter.operator_present
3193 && opnd->imm.value == get_optional_operand_default_value (opcode))
3194 break;
3195 enum_value = opnd->imm.value;
3196 assert (enum_value < ARRAY_SIZE (aarch64_sve_pattern_array));
3197 if (aarch64_sve_pattern_array[opnd->imm.value])
3198 snprintf (buf, size, "%s", aarch64_sve_pattern_array[opnd->imm.value]);
3199 else
3200 snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
3201 if (opnd->shifter.operator_present)
3202 {
3203 size_t len = strlen (buf);
3204 snprintf (buf + len, size - len, ", %s #%" PRIi64,
3205 aarch64_operand_modifiers[opnd->shifter.kind].name,
3206 opnd->shifter.amount);
3207 }
3208 break;
3209
245d2e3f
RS
3210 case AARCH64_OPND_SVE_PRFOP:
3211 enum_value = opnd->imm.value;
3212 assert (enum_value < ARRAY_SIZE (aarch64_sve_prfop_array));
3213 if (aarch64_sve_prfop_array[enum_value])
3214 snprintf (buf, size, "%s", aarch64_sve_prfop_array[enum_value]);
3215 else
3216 snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
3217 break;
3218
fb098a1e
YZ
3219 case AARCH64_OPND_IMM_MOV:
3220 switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
3221 {
3222 case 4: /* e.g. MOV Wd, #<imm32>. */
3223 {
3224 int imm32 = opnd->imm.value;
3225 snprintf (buf, size, "#0x%-20x\t// #%d", imm32, imm32);
3226 }
3227 break;
3228 case 8: /* e.g. MOV Xd, #<imm64>. */
3229 snprintf (buf, size, "#0x%-20" PRIx64 "\t// #%" PRIi64,
3230 opnd->imm.value, opnd->imm.value);
3231 break;
3232 default: assert (0);
3233 }
3234 break;
3235
a06ea964
NC
3236 case AARCH64_OPND_FPIMM0:
3237 snprintf (buf, size, "#0.0");
3238 break;
3239
3240 case AARCH64_OPND_LIMM:
3241 case AARCH64_OPND_AIMM:
3242 case AARCH64_OPND_HALF:
e950b345
RS
3243 case AARCH64_OPND_SVE_INV_LIMM:
3244 case AARCH64_OPND_SVE_LIMM:
3245 case AARCH64_OPND_SVE_LIMM_MOV:
a06ea964 3246 if (opnd->shifter.amount)
2442d846 3247 snprintf (buf, size, "#0x%" PRIx64 ", lsl #%" PRIi64, opnd->imm.value,
a06ea964
NC
3248 opnd->shifter.amount);
3249 else
3250 snprintf (buf, size, "#0x%" PRIx64, opnd->imm.value);
3251 break;
3252
3253 case AARCH64_OPND_SIMD_IMM:
3254 case AARCH64_OPND_SIMD_IMM_SFT:
3255 if ((! opnd->shifter.amount && opnd->shifter.kind == AARCH64_MOD_LSL)
3256 || opnd->shifter.kind == AARCH64_MOD_NONE)
3257 snprintf (buf, size, "#0x%" PRIx64, opnd->imm.value);
3258 else
2442d846 3259 snprintf (buf, size, "#0x%" PRIx64 ", %s #%" PRIi64, opnd->imm.value,
a06ea964
NC
3260 aarch64_operand_modifiers[opnd->shifter.kind].name,
3261 opnd->shifter.amount);
3262 break;
3263
e950b345
RS
3264 case AARCH64_OPND_SVE_AIMM:
3265 case AARCH64_OPND_SVE_ASIMM:
3266 if (opnd->shifter.amount)
3267 snprintf (buf, size, "#%" PRIi64 ", lsl #%" PRIi64, opnd->imm.value,
3268 opnd->shifter.amount);
3269 else
3270 snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
3271 break;
3272
a06ea964
NC
3273 case AARCH64_OPND_FPIMM:
3274 case AARCH64_OPND_SIMD_FPIMM:
165d4950 3275 case AARCH64_OPND_SVE_FPIMM8:
a06ea964
NC
3276 switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
3277 {
cf86120b
MW
3278 case 2: /* e.g. FMOV <Hd>, #<imm>. */
3279 {
3280 half_conv_t c;
3281 c.i = expand_fp_imm (2, opnd->imm.value);
3282 snprintf (buf, size, "#%.18e", c.f);
3283 }
3284 break;
a06ea964
NC
3285 case 4: /* e.g. FMOV <Vd>.4S, #<imm>. */
3286 {
3287 single_conv_t c;
cf86120b 3288 c.i = expand_fp_imm (4, opnd->imm.value);
a06ea964
NC
3289 snprintf (buf, size, "#%.18e", c.f);
3290 }
3291 break;
3292 case 8: /* e.g. FMOV <Sd>, #<imm>. */
3293 {
3294 double_conv_t c;
cf86120b 3295 c.i = expand_fp_imm (8, opnd->imm.value);
a06ea964
NC
3296 snprintf (buf, size, "#%.18e", c.d);
3297 }
3298 break;
3299 default: assert (0);
3300 }
3301 break;
3302
3303 case AARCH64_OPND_CCMP_IMM:
3304 case AARCH64_OPND_NZCV:
3305 case AARCH64_OPND_EXCEPTION:
3306 case AARCH64_OPND_UIMM4:
3307 case AARCH64_OPND_UIMM7:
3308 if (optional_operand_p (opcode, idx) == TRUE
3309 && (opnd->imm.value ==
3310 (int64_t) get_optional_operand_default_value (opcode)))
3311 /* Omit the operand, e.g. DCPS1. */
3312 break;
3313 snprintf (buf, size, "#0x%x", (unsigned int)opnd->imm.value);
3314 break;
3315
3316 case AARCH64_OPND_COND:
68a64283 3317 case AARCH64_OPND_COND1:
a06ea964 3318 snprintf (buf, size, "%s", opnd->cond->names[0]);
bb7eff52
RS
3319 num_conds = ARRAY_SIZE (opnd->cond->names);
3320 for (i = 1; i < num_conds && opnd->cond->names[i]; ++i)
3321 {
3322 size_t len = strlen (buf);
3323 if (i == 1)
3324 snprintf (buf + len, size - len, " // %s = %s",
3325 opnd->cond->names[0], opnd->cond->names[i]);
3326 else
3327 snprintf (buf + len, size - len, ", %s",
3328 opnd->cond->names[i]);
3329 }
a06ea964
NC
3330 break;
3331
3332 case AARCH64_OPND_ADDR_ADRP:
3333 addr = ((pc + AARCH64_PCREL_OFFSET) & ~(uint64_t)0xfff)
3334 + opnd->imm.value;
3335 if (pcrel_p)
3336 *pcrel_p = 1;
3337 if (address)
3338 *address = addr;
3339 /* This is not necessary during the disassembling, as print_address_func
3340 in the disassemble_info will take care of the printing. But some
3341 other callers may be still interested in getting the string in *STR,
3342 so here we do snprintf regardless. */
3343 snprintf (buf, size, "#0x%" PRIx64, addr);
3344 break;
3345
3346 case AARCH64_OPND_ADDR_PCREL14:
3347 case AARCH64_OPND_ADDR_PCREL19:
3348 case AARCH64_OPND_ADDR_PCREL21:
3349 case AARCH64_OPND_ADDR_PCREL26:
3350 addr = pc + AARCH64_PCREL_OFFSET + opnd->imm.value;
3351 if (pcrel_p)
3352 *pcrel_p = 1;
3353 if (address)
3354 *address = addr;
3355 /* This is not necessary during the disassembling, as print_address_func
3356 in the disassemble_info will take care of the printing. But some
3357 other callers may be still interested in getting the string in *STR,
3358 so here we do snprintf regardless. */
3359 snprintf (buf, size, "#0x%" PRIx64, addr);
3360 break;
3361
3362 case AARCH64_OPND_ADDR_SIMPLE:
3363 case AARCH64_OPND_SIMD_ADDR_SIMPLE:
3364 case AARCH64_OPND_SIMD_ADDR_POST:
3365 name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
3366 if (opnd->type == AARCH64_OPND_SIMD_ADDR_POST)
3367 {
3368 if (opnd->addr.offset.is_reg)
3369 snprintf (buf, size, "[%s], x%d", name, opnd->addr.offset.regno);
3370 else
3371 snprintf (buf, size, "[%s], #%d", name, opnd->addr.offset.imm);
3372 }
3373 else
3374 snprintf (buf, size, "[%s]", name);
3375 break;
3376
3377 case AARCH64_OPND_ADDR_REGOFF:
4df068de
RS
3378 case AARCH64_OPND_SVE_ADDR_RR:
3379 case AARCH64_OPND_SVE_ADDR_RR_LSL1:
3380 case AARCH64_OPND_SVE_ADDR_RR_LSL2:
3381 case AARCH64_OPND_SVE_ADDR_RR_LSL3:
3382 case AARCH64_OPND_SVE_ADDR_RX:
3383 case AARCH64_OPND_SVE_ADDR_RX_LSL1:
3384 case AARCH64_OPND_SVE_ADDR_RX_LSL2:
3385 case AARCH64_OPND_SVE_ADDR_RX_LSL3:
01dbfe4c
RS
3386 print_register_offset_address
3387 (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
3388 get_offset_int_reg_name (opnd));
a06ea964
NC
3389 break;
3390
4df068de
RS
3391 case AARCH64_OPND_SVE_ADDR_RZ:
3392 case AARCH64_OPND_SVE_ADDR_RZ_LSL1:
3393 case AARCH64_OPND_SVE_ADDR_RZ_LSL2:
3394 case AARCH64_OPND_SVE_ADDR_RZ_LSL3:
3395 case AARCH64_OPND_SVE_ADDR_RZ_XTW_14:
3396 case AARCH64_OPND_SVE_ADDR_RZ_XTW_22:
3397 case AARCH64_OPND_SVE_ADDR_RZ_XTW1_14:
3398 case AARCH64_OPND_SVE_ADDR_RZ_XTW1_22:
3399 case AARCH64_OPND_SVE_ADDR_RZ_XTW2_14:
3400 case AARCH64_OPND_SVE_ADDR_RZ_XTW2_22:
3401 case AARCH64_OPND_SVE_ADDR_RZ_XTW3_14:
3402 case AARCH64_OPND_SVE_ADDR_RZ_XTW3_22:
3403 print_register_offset_address
3404 (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
3405 get_addr_sve_reg_name (opnd->addr.offset.regno, opnd->qualifier));
3406 break;
3407
a06ea964
NC
3408 case AARCH64_OPND_ADDR_SIMM7:
3409 case AARCH64_OPND_ADDR_SIMM9:
3410 case AARCH64_OPND_ADDR_SIMM9_2:
98907a70
RS
3411 case AARCH64_OPND_SVE_ADDR_RI_S4xVL:
3412 case AARCH64_OPND_SVE_ADDR_RI_S4x2xVL:
3413 case AARCH64_OPND_SVE_ADDR_RI_S4x3xVL:
3414 case AARCH64_OPND_SVE_ADDR_RI_S4x4xVL:
3415 case AARCH64_OPND_SVE_ADDR_RI_S6xVL:
3416 case AARCH64_OPND_SVE_ADDR_RI_S9xVL:
4df068de
RS
3417 case AARCH64_OPND_SVE_ADDR_RI_U6:
3418 case AARCH64_OPND_SVE_ADDR_RI_U6x2:
3419 case AARCH64_OPND_SVE_ADDR_RI_U6x4:
3420 case AARCH64_OPND_SVE_ADDR_RI_U6x8:
01dbfe4c
RS
3421 print_immediate_offset_address
3422 (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1));
a06ea964
NC
3423 break;
3424
4df068de
RS
3425 case AARCH64_OPND_SVE_ADDR_ZI_U5:
3426 case AARCH64_OPND_SVE_ADDR_ZI_U5x2:
3427 case AARCH64_OPND_SVE_ADDR_ZI_U5x4:
3428 case AARCH64_OPND_SVE_ADDR_ZI_U5x8:
3429 print_immediate_offset_address
3430 (buf, size, opnd,
3431 get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier));
3432 break;
3433
3434 case AARCH64_OPND_SVE_ADDR_ZZ_LSL:
3435 case AARCH64_OPND_SVE_ADDR_ZZ_SXTW:
3436 case AARCH64_OPND_SVE_ADDR_ZZ_UXTW:
3437 print_register_offset_address
3438 (buf, size, opnd,
3439 get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier),
3440 get_addr_sve_reg_name (opnd->addr.offset.regno, opnd->qualifier));
3441 break;
3442
a06ea964
NC
3443 case AARCH64_OPND_ADDR_UIMM12:
3444 name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
3445 if (opnd->addr.offset.imm)
ad43e107 3446 snprintf (buf, size, "[%s, #%d]", name, opnd->addr.offset.imm);
a06ea964
NC
3447 else
3448 snprintf (buf, size, "[%s]", name);
3449 break;
3450
3451 case AARCH64_OPND_SYSREG:
3452 for (i = 0; aarch64_sys_regs[i].name; ++i)
49eec193
YZ
3453 if (aarch64_sys_regs[i].value == opnd->sysreg
3454 && ! aarch64_sys_reg_deprecated_p (&aarch64_sys_regs[i]))
a06ea964
NC
3455 break;
3456 if (aarch64_sys_regs[i].name)
3457 snprintf (buf, size, "%s", aarch64_sys_regs[i].name);
3458 else
3459 {
3460 /* Implementation defined system register. */
3461 unsigned int value = opnd->sysreg;
3462 snprintf (buf, size, "s%u_%u_c%u_c%u_%u", (value >> 14) & 0x3,
3463 (value >> 11) & 0x7, (value >> 7) & 0xf, (value >> 3) & 0xf,
3464 value & 0x7);
3465 }
3466 break;
3467
3468 case AARCH64_OPND_PSTATEFIELD:
3469 for (i = 0; aarch64_pstatefields[i].name; ++i)
3470 if (aarch64_pstatefields[i].value == opnd->pstatefield)
3471 break;
3472 assert (aarch64_pstatefields[i].name);
3473 snprintf (buf, size, "%s", aarch64_pstatefields[i].name);
3474 break;
3475
3476 case AARCH64_OPND_SYSREG_AT:
3477 case AARCH64_OPND_SYSREG_DC:
3478 case AARCH64_OPND_SYSREG_IC:
3479 case AARCH64_OPND_SYSREG_TLBI:
875880c6 3480 snprintf (buf, size, "%s", opnd->sysins_op->name);
a06ea964
NC
3481 break;
3482
3483 case AARCH64_OPND_BARRIER:
3484 snprintf (buf, size, "%s", opnd->barrier->name);
3485 break;
3486
3487 case AARCH64_OPND_BARRIER_ISB:
3488 /* Operand can be omitted, e.g. in DCPS1. */
3489 if (! optional_operand_p (opcode, idx)
3490 || (opnd->barrier->value
3491 != get_optional_operand_default_value (opcode)))
3492 snprintf (buf, size, "#0x%x", opnd->barrier->value);
3493 break;
3494
3495 case AARCH64_OPND_PRFOP:
a1ccaec9
YZ
3496 if (opnd->prfop->name != NULL)
3497 snprintf (buf, size, "%s", opnd->prfop->name);
3498 else
3499 snprintf (buf, size, "#0x%02x", opnd->prfop->value);
a06ea964
NC
3500 break;
3501
1e6f4800
MW
3502 case AARCH64_OPND_BARRIER_PSB:
3503 snprintf (buf, size, "%s", opnd->hint_option->name);
3504 break;
3505
a06ea964
NC
3506 default:
3507 assert (0);
3508 }
3509}
3510\f
3511#define CPENC(op0,op1,crn,crm,op2) \
3512 ((((op0) << 19) | ((op1) << 16) | ((crn) << 12) | ((crm) << 8) | ((op2) << 5)) >> 5)
3513 /* for 3.9.3 Instructions for Accessing Special Purpose Registers */
3514#define CPEN_(op1,crm,op2) CPENC(3,(op1),4,(crm),(op2))
3515 /* for 3.9.10 System Instructions */
3516#define CPENS(op1,crn,crm,op2) CPENC(1,(op1),(crn),(crm),(op2))
3517
3518#define C0 0
3519#define C1 1
3520#define C2 2
3521#define C3 3
3522#define C4 4
3523#define C5 5
3524#define C6 6
3525#define C7 7
3526#define C8 8
3527#define C9 9
3528#define C10 10
3529#define C11 11
3530#define C12 12
3531#define C13 13
3532#define C14 14
3533#define C15 15
3534
49eec193
YZ
3535#ifdef F_DEPRECATED
3536#undef F_DEPRECATED
3537#endif
3538#define F_DEPRECATED 0x1 /* Deprecated system register. */
3539
f21cce2c
MW
3540#ifdef F_ARCHEXT
3541#undef F_ARCHEXT
3542#endif
3543#define F_ARCHEXT 0x2 /* Architecture dependent system register. */
3544
ea2deeec
MW
3545#ifdef F_HASXT
3546#undef F_HASXT
3547#endif
3548#define F_HASXT 0x4 /* System instruction register <Xt>
3549 operand. */
3550
f21cce2c 3551
a06ea964
NC
3552/* TODO there are two more issues need to be resolved
3553 1. handle read-only and write-only system registers
3554 2. handle cpu-implementation-defined system registers. */
49eec193
YZ
3555const aarch64_sys_reg aarch64_sys_regs [] =
3556{
3557 { "spsr_el1", CPEN_(0,C0,0), 0 }, /* = spsr_svc */
250aafa4 3558 { "spsr_el12", CPEN_ (5, C0, 0), F_ARCHEXT },
49eec193 3559 { "elr_el1", CPEN_(0,C0,1), 0 },
250aafa4 3560 { "elr_el12", CPEN_ (5, C0, 1), F_ARCHEXT },
49eec193
YZ
3561 { "sp_el0", CPEN_(0,C1,0), 0 },
3562 { "spsel", CPEN_(0,C2,0), 0 },
3563 { "daif", CPEN_(3,C2,1), 0 },
3564 { "currentel", CPEN_(0,C2,2), 0 }, /* RO */
f21cce2c 3565 { "pan", CPEN_(0,C2,3), F_ARCHEXT },
6479e48e 3566 { "uao", CPEN_ (0, C2, 4), F_ARCHEXT },
49eec193
YZ
3567 { "nzcv", CPEN_(3,C2,0), 0 },
3568 { "fpcr", CPEN_(3,C4,0), 0 },
3569 { "fpsr", CPEN_(3,C4,1), 0 },
3570 { "dspsr_el0", CPEN_(3,C5,0), 0 },
3571 { "dlr_el0", CPEN_(3,C5,1), 0 },
3572 { "spsr_el2", CPEN_(4,C0,0), 0 }, /* = spsr_hyp */
3573 { "elr_el2", CPEN_(4,C0,1), 0 },
3574 { "sp_el1", CPEN_(4,C1,0), 0 },
3575 { "spsr_irq", CPEN_(4,C3,0), 0 },
3576 { "spsr_abt", CPEN_(4,C3,1), 0 },
3577 { "spsr_und", CPEN_(4,C3,2), 0 },
3578 { "spsr_fiq", CPEN_(4,C3,3), 0 },
3579 { "spsr_el3", CPEN_(6,C0,0), 0 },
3580 { "elr_el3", CPEN_(6,C0,1), 0 },
3581 { "sp_el2", CPEN_(6,C1,0), 0 },
3582 { "spsr_svc", CPEN_(0,C0,0), F_DEPRECATED }, /* = spsr_el1 */
3583 { "spsr_hyp", CPEN_(4,C0,0), F_DEPRECATED }, /* = spsr_el2 */
3584 { "midr_el1", CPENC(3,0,C0,C0,0), 0 }, /* RO */
3585 { "ctr_el0", CPENC(3,3,C0,C0,1), 0 }, /* RO */
3586 { "mpidr_el1", CPENC(3,0,C0,C0,5), 0 }, /* RO */
3587 { "revidr_el1", CPENC(3,0,C0,C0,6), 0 }, /* RO */
3588 { "aidr_el1", CPENC(3,1,C0,C0,7), 0 }, /* RO */
3589 { "dczid_el0", CPENC(3,3,C0,C0,7), 0 }, /* RO */
3590 { "id_dfr0_el1", CPENC(3,0,C0,C1,2), 0 }, /* RO */
3591 { "id_pfr0_el1", CPENC(3,0,C0,C1,0), 0 }, /* RO */
3592 { "id_pfr1_el1", CPENC(3,0,C0,C1,1), 0 }, /* RO */
3593 { "id_afr0_el1", CPENC(3,0,C0,C1,3), 0 }, /* RO */
3594 { "id_mmfr0_el1", CPENC(3,0,C0,C1,4), 0 }, /* RO */
3595 { "id_mmfr1_el1", CPENC(3,0,C0,C1,5), 0 }, /* RO */
3596 { "id_mmfr2_el1", CPENC(3,0,C0,C1,6), 0 }, /* RO */
3597 { "id_mmfr3_el1", CPENC(3,0,C0,C1,7), 0 }, /* RO */
bdfa8b95 3598 { "id_mmfr4_el1", CPENC(3,0,C0,C2,6), 0 }, /* RO */
49eec193
YZ
3599 { "id_isar0_el1", CPENC(3,0,C0,C2,0), 0 }, /* RO */
3600 { "id_isar1_el1", CPENC(3,0,C0,C2,1), 0 }, /* RO */
3601 { "id_isar2_el1", CPENC(3,0,C0,C2,2), 0 }, /* RO */
3602 { "id_isar3_el1", CPENC(3,0,C0,C2,3), 0 }, /* RO */
3603 { "id_isar4_el1", CPENC(3,0,C0,C2,4), 0 }, /* RO */
3604 { "id_isar5_el1", CPENC(3,0,C0,C2,5), 0 }, /* RO */
3605 { "mvfr0_el1", CPENC(3,0,C0,C3,0), 0 }, /* RO */
3606 { "mvfr1_el1", CPENC(3,0,C0,C3,1), 0 }, /* RO */
3607 { "mvfr2_el1", CPENC(3,0,C0,C3,2), 0 }, /* RO */
3608 { "ccsidr_el1", CPENC(3,1,C0,C0,0), 0 }, /* RO */
3609 { "id_aa64pfr0_el1", CPENC(3,0,C0,C4,0), 0 }, /* RO */
3610 { "id_aa64pfr1_el1", CPENC(3,0,C0,C4,1), 0 }, /* RO */
3611 { "id_aa64dfr0_el1", CPENC(3,0,C0,C5,0), 0 }, /* RO */
3612 { "id_aa64dfr1_el1", CPENC(3,0,C0,C5,1), 0 }, /* RO */
3613 { "id_aa64isar0_el1", CPENC(3,0,C0,C6,0), 0 }, /* RO */
3614 { "id_aa64isar1_el1", CPENC(3,0,C0,C6,1), 0 }, /* RO */
3615 { "id_aa64mmfr0_el1", CPENC(3,0,C0,C7,0), 0 }, /* RO */
3616 { "id_aa64mmfr1_el1", CPENC(3,0,C0,C7,1), 0 }, /* RO */
1a04d1a7 3617 { "id_aa64mmfr2_el1", CPENC (3, 0, C0, C7, 2), F_ARCHEXT }, /* RO */
49eec193
YZ
3618 { "id_aa64afr0_el1", CPENC(3,0,C0,C5,4), 0 }, /* RO */
3619 { "id_aa64afr1_el1", CPENC(3,0,C0,C5,5), 0 }, /* RO */
3620 { "clidr_el1", CPENC(3,1,C0,C0,1), 0 }, /* RO */
3621 { "csselr_el1", CPENC(3,2,C0,C0,0), 0 }, /* RO */
3622 { "vpidr_el2", CPENC(3,4,C0,C0,0), 0 },
3623 { "vmpidr_el2", CPENC(3,4,C0,C0,5), 0 },
3624 { "sctlr_el1", CPENC(3,0,C1,C0,0), 0 },
3625 { "sctlr_el2", CPENC(3,4,C1,C0,0), 0 },
3626 { "sctlr_el3", CPENC(3,6,C1,C0,0), 0 },
250aafa4 3627 { "sctlr_el12", CPENC (3, 5, C1, C0, 0), F_ARCHEXT },
49eec193
YZ
3628 { "actlr_el1", CPENC(3,0,C1,C0,1), 0 },
3629 { "actlr_el2", CPENC(3,4,C1,C0,1), 0 },
3630 { "actlr_el3", CPENC(3,6,C1,C0,1), 0 },
3631 { "cpacr_el1", CPENC(3,0,C1,C0,2), 0 },
250aafa4 3632 { "cpacr_el12", CPENC (3, 5, C1, C0, 2), F_ARCHEXT },
49eec193
YZ
3633 { "cptr_el2", CPENC(3,4,C1,C1,2), 0 },
3634 { "cptr_el3", CPENC(3,6,C1,C1,2), 0 },
3635 { "scr_el3", CPENC(3,6,C1,C1,0), 0 },
3636 { "hcr_el2", CPENC(3,4,C1,C1,0), 0 },
3637 { "mdcr_el2", CPENC(3,4,C1,C1,1), 0 },
3638 { "mdcr_el3", CPENC(3,6,C1,C3,1), 0 },
3639 { "hstr_el2", CPENC(3,4,C1,C1,3), 0 },
3640 { "hacr_el2", CPENC(3,4,C1,C1,7), 0 },
3641 { "ttbr0_el1", CPENC(3,0,C2,C0,0), 0 },
3642 { "ttbr1_el1", CPENC(3,0,C2,C0,1), 0 },
3643 { "ttbr0_el2", CPENC(3,4,C2,C0,0), 0 },
250aafa4 3644 { "ttbr1_el2", CPENC (3, 4, C2, C0, 1), F_ARCHEXT },
49eec193 3645 { "ttbr0_el3", CPENC(3,6,C2,C0,0), 0 },
250aafa4
MW
3646 { "ttbr0_el12", CPENC (3, 5, C2, C0, 0), F_ARCHEXT },
3647 { "ttbr1_el12", CPENC (3, 5, C2, C0, 1), F_ARCHEXT },
49eec193
YZ
3648 { "vttbr_el2", CPENC(3,4,C2,C1,0), 0 },
3649 { "tcr_el1", CPENC(3,0,C2,C0,2), 0 },
3650 { "tcr_el2", CPENC(3,4,C2,C0,2), 0 },
3651 { "tcr_el3", CPENC(3,6,C2,C0,2), 0 },
250aafa4 3652 { "tcr_el12", CPENC (3, 5, C2, C0, 2), F_ARCHEXT },
49eec193 3653 { "vtcr_el2", CPENC(3,4,C2,C1,2), 0 },
b0bfa7b5
SN
3654 { "apiakeylo_el1", CPENC (3, 0, C2, C1, 0), F_ARCHEXT },
3655 { "apiakeyhi_el1", CPENC (3, 0, C2, C1, 1), F_ARCHEXT },
3656 { "apibkeylo_el1", CPENC (3, 0, C2, C1, 2), F_ARCHEXT },
3657 { "apibkeyhi_el1", CPENC (3, 0, C2, C1, 3), F_ARCHEXT },
3658 { "apdakeylo_el1", CPENC (3, 0, C2, C2, 0), F_ARCHEXT },
3659 { "apdakeyhi_el1", CPENC (3, 0, C2, C2, 1), F_ARCHEXT },
3660 { "apdbkeylo_el1", CPENC (3, 0, C2, C2, 2), F_ARCHEXT },
3661 { "apdbkeyhi_el1", CPENC (3, 0, C2, C2, 3), F_ARCHEXT },
3662 { "apgakeylo_el1", CPENC (3, 0, C2, C3, 0), F_ARCHEXT },
3663 { "apgakeyhi_el1", CPENC (3, 0, C2, C3, 1), F_ARCHEXT },
49eec193
YZ
3664 { "afsr0_el1", CPENC(3,0,C5,C1,0), 0 },
3665 { "afsr1_el1", CPENC(3,0,C5,C1,1), 0 },
3666 { "afsr0_el2", CPENC(3,4,C5,C1,0), 0 },
3667 { "afsr1_el2", CPENC(3,4,C5,C1,1), 0 },
3668 { "afsr0_el3", CPENC(3,6,C5,C1,0), 0 },
250aafa4 3669 { "afsr0_el12", CPENC (3, 5, C5, C1, 0), F_ARCHEXT },
49eec193 3670 { "afsr1_el3", CPENC(3,6,C5,C1,1), 0 },
250aafa4 3671 { "afsr1_el12", CPENC (3, 5, C5, C1, 1), F_ARCHEXT },
49eec193
YZ
3672 { "esr_el1", CPENC(3,0,C5,C2,0), 0 },
3673 { "esr_el2", CPENC(3,4,C5,C2,0), 0 },
3674 { "esr_el3", CPENC(3,6,C5,C2,0), 0 },
250aafa4 3675 { "esr_el12", CPENC (3, 5, C5, C2, 0), F_ARCHEXT },
47f81142 3676 { "vsesr_el2", CPENC (3, 4, C5, C2, 3), F_ARCHEXT }, /* RO */
49eec193 3677 { "fpexc32_el2", CPENC(3,4,C5,C3,0), 0 },
47f81142
MW
3678 { "erridr_el1", CPENC (3, 0, C5, C3, 0), F_ARCHEXT }, /* RO */
3679 { "errselr_el1", CPENC (3, 0, C5, C3, 1), F_ARCHEXT },
3680 { "erxfr_el1", CPENC (3, 0, C5, C4, 0), F_ARCHEXT }, /* RO */
3681 { "erxctlr_el1", CPENC (3, 0, C5, C4, 1), F_ARCHEXT },
3682 { "erxstatus_el1", CPENC (3, 0, C5, C4, 2), F_ARCHEXT },
3683 { "erxaddr_el1", CPENC (3, 0, C5, C4, 3), F_ARCHEXT },
3684 { "erxmisc0_el1", CPENC (3, 0, C5, C5, 0), F_ARCHEXT },
3685 { "erxmisc1_el1", CPENC (3, 0, C5, C5, 1), F_ARCHEXT },
49eec193
YZ
3686 { "far_el1", CPENC(3,0,C6,C0,0), 0 },
3687 { "far_el2", CPENC(3,4,C6,C0,0), 0 },
3688 { "far_el3", CPENC(3,6,C6,C0,0), 0 },
250aafa4 3689 { "far_el12", CPENC (3, 5, C6, C0, 0), F_ARCHEXT },
49eec193
YZ
3690 { "hpfar_el2", CPENC(3,4,C6,C0,4), 0 },
3691 { "par_el1", CPENC(3,0,C7,C4,0), 0 },
3692 { "mair_el1", CPENC(3,0,C10,C2,0), 0 },
3693 { "mair_el2", CPENC(3,4,C10,C2,0), 0 },
3694 { "mair_el3", CPENC(3,6,C10,C2,0), 0 },
250aafa4 3695 { "mair_el12", CPENC (3, 5, C10, C2, 0), F_ARCHEXT },
49eec193
YZ
3696 { "amair_el1", CPENC(3,0,C10,C3,0), 0 },
3697 { "amair_el2", CPENC(3,4,C10,C3,0), 0 },
3698 { "amair_el3", CPENC(3,6,C10,C3,0), 0 },
250aafa4 3699 { "amair_el12", CPENC (3, 5, C10, C3, 0), F_ARCHEXT },
49eec193
YZ
3700 { "vbar_el1", CPENC(3,0,C12,C0,0), 0 },
3701 { "vbar_el2", CPENC(3,4,C12,C0,0), 0 },
3702 { "vbar_el3", CPENC(3,6,C12,C0,0), 0 },
250aafa4 3703 { "vbar_el12", CPENC (3, 5, C12, C0, 0), F_ARCHEXT },
49eec193
YZ
3704 { "rvbar_el1", CPENC(3,0,C12,C0,1), 0 }, /* RO */
3705 { "rvbar_el2", CPENC(3,4,C12,C0,1), 0 }, /* RO */
3706 { "rvbar_el3", CPENC(3,6,C12,C0,1), 0 }, /* RO */
3707 { "rmr_el1", CPENC(3,0,C12,C0,2), 0 },
3708 { "rmr_el2", CPENC(3,4,C12,C0,2), 0 },
3709 { "rmr_el3", CPENC(3,6,C12,C0,2), 0 },
3710 { "isr_el1", CPENC(3,0,C12,C1,0), 0 }, /* RO */
47f81142
MW
3711 { "disr_el1", CPENC (3, 0, C12, C1, 1), F_ARCHEXT },
3712 { "vdisr_el2", CPENC (3, 4, C12, C1, 1), F_ARCHEXT },
49eec193 3713 { "contextidr_el1", CPENC(3,0,C13,C0,1), 0 },
250aafa4
MW
3714 { "contextidr_el2", CPENC (3, 4, C13, C0, 1), F_ARCHEXT },
3715 { "contextidr_el12", CPENC (3, 5, C13, C0, 1), F_ARCHEXT },
49eec193
YZ
3716 { "tpidr_el0", CPENC(3,3,C13,C0,2), 0 },
3717 { "tpidrro_el0", CPENC(3,3,C13,C0,3), 0 }, /* RO */
3718 { "tpidr_el1", CPENC(3,0,C13,C0,4), 0 },
3719 { "tpidr_el2", CPENC(3,4,C13,C0,2), 0 },
3720 { "tpidr_el3", CPENC(3,6,C13,C0,2), 0 },
3721 { "teecr32_el1", CPENC(2,2,C0, C0,0), 0 }, /* See section 3.9.7.1 */
3722 { "cntfrq_el0", CPENC(3,3,C14,C0,0), 0 }, /* RO */
3723 { "cntpct_el0", CPENC(3,3,C14,C0,1), 0 }, /* RO */
3724 { "cntvct_el0", CPENC(3,3,C14,C0,2), 0 }, /* RO */
3725 { "cntvoff_el2", CPENC(3,4,C14,C0,3), 0 },
3726 { "cntkctl_el1", CPENC(3,0,C14,C1,0), 0 },
250aafa4 3727 { "cntkctl_el12", CPENC (3, 5, C14, C1, 0), F_ARCHEXT },
49eec193
YZ
3728 { "cnthctl_el2", CPENC(3,4,C14,C1,0), 0 },
3729 { "cntp_tval_el0", CPENC(3,3,C14,C2,0), 0 },
250aafa4 3730 { "cntp_tval_el02", CPENC (3, 5, C14, C2, 0), F_ARCHEXT },
49eec193 3731 { "cntp_ctl_el0", CPENC(3,3,C14,C2,1), 0 },
250aafa4 3732 { "cntp_ctl_el02", CPENC (3, 5, C14, C2, 1), F_ARCHEXT },
49eec193 3733 { "cntp_cval_el0", CPENC(3,3,C14,C2,2), 0 },
250aafa4 3734 { "cntp_cval_el02", CPENC (3, 5, C14, C2, 2), F_ARCHEXT },
49eec193 3735 { "cntv_tval_el0", CPENC(3,3,C14,C3,0), 0 },
250aafa4 3736 { "cntv_tval_el02", CPENC (3, 5, C14, C3, 0), F_ARCHEXT },
49eec193 3737 { "cntv_ctl_el0", CPENC(3,3,C14,C3,1), 0 },
250aafa4 3738 { "cntv_ctl_el02", CPENC (3, 5, C14, C3, 1), F_ARCHEXT },
49eec193 3739 { "cntv_cval_el0", CPENC(3,3,C14,C3,2), 0 },
250aafa4 3740 { "cntv_cval_el02", CPENC (3, 5, C14, C3, 2), F_ARCHEXT },
49eec193
YZ
3741 { "cnthp_tval_el2", CPENC(3,4,C14,C2,0), 0 },
3742 { "cnthp_ctl_el2", CPENC(3,4,C14,C2,1), 0 },
3743 { "cnthp_cval_el2", CPENC(3,4,C14,C2,2), 0 },
3744 { "cntps_tval_el1", CPENC(3,7,C14,C2,0), 0 },
3745 { "cntps_ctl_el1", CPENC(3,7,C14,C2,1), 0 },
3746 { "cntps_cval_el1", CPENC(3,7,C14,C2,2), 0 },
250aafa4
MW
3747 { "cnthv_tval_el2", CPENC (3, 4, C14, C3, 0), F_ARCHEXT },
3748 { "cnthv_ctl_el2", CPENC (3, 4, C14, C3, 1), F_ARCHEXT },
3749 { "cnthv_cval_el2", CPENC (3, 4, C14, C3, 2), F_ARCHEXT },
49eec193
YZ
3750 { "dacr32_el2", CPENC(3,4,C3,C0,0), 0 },
3751 { "ifsr32_el2", CPENC(3,4,C5,C0,1), 0 },
3752 { "teehbr32_el1", CPENC(2,2,C1,C0,0), 0 },
3753 { "sder32_el3", CPENC(3,6,C1,C1,1), 0 },
3754 { "mdscr_el1", CPENC(2,0,C0, C2, 2), 0 },
3755 { "mdccsr_el0", CPENC(2,3,C0, C1, 0), 0 }, /* r */
3756 { "mdccint_el1", CPENC(2,0,C0, C2, 0), 0 },
3757 { "dbgdtr_el0", CPENC(2,3,C0, C4, 0), 0 },
3758 { "dbgdtrrx_el0", CPENC(2,3,C0, C5, 0), 0 }, /* r */
3759 { "dbgdtrtx_el0", CPENC(2,3,C0, C5, 0), 0 }, /* w */
3760 { "osdtrrx_el1", CPENC(2,0,C0, C0, 2), 0 }, /* r */
3761 { "osdtrtx_el1", CPENC(2,0,C0, C3, 2), 0 }, /* w */
3762 { "oseccr_el1", CPENC(2,0,C0, C6, 2), 0 },
3763 { "dbgvcr32_el2", CPENC(2,4,C0, C7, 0), 0 },
3764 { "dbgbvr0_el1", CPENC(2,0,C0, C0, 4), 0 },
3765 { "dbgbvr1_el1", CPENC(2,0,C0, C1, 4), 0 },
3766 { "dbgbvr2_el1", CPENC(2,0,C0, C2, 4), 0 },
3767 { "dbgbvr3_el1", CPENC(2,0,C0, C3, 4), 0 },
3768 { "dbgbvr4_el1", CPENC(2,0,C0, C4, 4), 0 },
3769 { "dbgbvr5_el1", CPENC(2,0,C0, C5, 4), 0 },
3770 { "dbgbvr6_el1", CPENC(2,0,C0, C6, 4), 0 },
3771 { "dbgbvr7_el1", CPENC(2,0,C0, C7, 4), 0 },
3772 { "dbgbvr8_el1", CPENC(2,0,C0, C8, 4), 0 },
3773 { "dbgbvr9_el1", CPENC(2,0,C0, C9, 4), 0 },
3774 { "dbgbvr10_el1", CPENC(2,0,C0, C10,4), 0 },
3775 { "dbgbvr11_el1", CPENC(2,0,C0, C11,4), 0 },
3776 { "dbgbvr12_el1", CPENC(2,0,C0, C12,4), 0 },
3777 { "dbgbvr13_el1", CPENC(2,0,C0, C13,4), 0 },
3778 { "dbgbvr14_el1", CPENC(2,0,C0, C14,4), 0 },
3779 { "dbgbvr15_el1", CPENC(2,0,C0, C15,4), 0 },
3780 { "dbgbcr0_el1", CPENC(2,0,C0, C0, 5), 0 },
3781 { "dbgbcr1_el1", CPENC(2,0,C0, C1, 5), 0 },
3782 { "dbgbcr2_el1", CPENC(2,0,C0, C2, 5), 0 },
3783 { "dbgbcr3_el1", CPENC(2,0,C0, C3, 5), 0 },
3784 { "dbgbcr4_el1", CPENC(2,0,C0, C4, 5), 0 },
3785 { "dbgbcr5_el1", CPENC(2,0,C0, C5, 5), 0 },
3786 { "dbgbcr6_el1", CPENC(2,0,C0, C6, 5), 0 },
3787 { "dbgbcr7_el1", CPENC(2,0,C0, C7, 5), 0 },
3788 { "dbgbcr8_el1", CPENC(2,0,C0, C8, 5), 0 },
3789 { "dbgbcr9_el1", CPENC(2,0,C0, C9, 5), 0 },
3790 { "dbgbcr10_el1", CPENC(2,0,C0, C10,5), 0 },
3791 { "dbgbcr11_el1", CPENC(2,0,C0, C11,5), 0 },
3792 { "dbgbcr12_el1", CPENC(2,0,C0, C12,5), 0 },
3793 { "dbgbcr13_el1", CPENC(2,0,C0, C13,5), 0 },
3794 { "dbgbcr14_el1", CPENC(2,0,C0, C14,5), 0 },
3795 { "dbgbcr15_el1", CPENC(2,0,C0, C15,5), 0 },
3796 { "dbgwvr0_el1", CPENC(2,0,C0, C0, 6), 0 },
3797 { "dbgwvr1_el1", CPENC(2,0,C0, C1, 6), 0 },
3798 { "dbgwvr2_el1", CPENC(2,0,C0, C2, 6), 0 },
3799 { "dbgwvr3_el1", CPENC(2,0,C0, C3, 6), 0 },
3800 { "dbgwvr4_el1", CPENC(2,0,C0, C4, 6), 0 },
3801 { "dbgwvr5_el1", CPENC(2,0,C0, C5, 6), 0 },
3802 { "dbgwvr6_el1", CPENC(2,0,C0, C6, 6), 0 },
3803 { "dbgwvr7_el1", CPENC(2,0,C0, C7, 6), 0 },
3804 { "dbgwvr8_el1", CPENC(2,0,C0, C8, 6), 0 },
3805 { "dbgwvr9_el1", CPENC(2,0,C0, C9, 6), 0 },
3806 { "dbgwvr10_el1", CPENC(2,0,C0, C10,6), 0 },
3807 { "dbgwvr11_el1", CPENC(2,0,C0, C11,6), 0 },
3808 { "dbgwvr12_el1", CPENC(2,0,C0, C12,6), 0 },
3809 { "dbgwvr13_el1", CPENC(2,0,C0, C13,6), 0 },
3810 { "dbgwvr14_el1", CPENC(2,0,C0, C14,6), 0 },
3811 { "dbgwvr15_el1", CPENC(2,0,C0, C15,6), 0 },
3812 { "dbgwcr0_el1", CPENC(2,0,C0, C0, 7), 0 },
3813 { "dbgwcr1_el1", CPENC(2,0,C0, C1, 7), 0 },
3814 { "dbgwcr2_el1", CPENC(2,0,C0, C2, 7), 0 },
3815 { "dbgwcr3_el1", CPENC(2,0,C0, C3, 7), 0 },
3816 { "dbgwcr4_el1", CPENC(2,0,C0, C4, 7), 0 },
3817 { "dbgwcr5_el1", CPENC(2,0,C0, C5, 7), 0 },
3818 { "dbgwcr6_el1", CPENC(2,0,C0, C6, 7), 0 },
3819 { "dbgwcr7_el1", CPENC(2,0,C0, C7, 7), 0 },
3820 { "dbgwcr8_el1", CPENC(2,0,C0, C8, 7), 0 },
3821 { "dbgwcr9_el1", CPENC(2,0,C0, C9, 7), 0 },
3822 { "dbgwcr10_el1", CPENC(2,0,C0, C10,7), 0 },
3823 { "dbgwcr11_el1", CPENC(2,0,C0, C11,7), 0 },
3824 { "dbgwcr12_el1", CPENC(2,0,C0, C12,7), 0 },
3825 { "dbgwcr13_el1", CPENC(2,0,C0, C13,7), 0 },
3826 { "dbgwcr14_el1", CPENC(2,0,C0, C14,7), 0 },
3827 { "dbgwcr15_el1", CPENC(2,0,C0, C15,7), 0 },
3828 { "mdrar_el1", CPENC(2,0,C1, C0, 0), 0 }, /* r */
3829 { "oslar_el1", CPENC(2,0,C1, C0, 4), 0 }, /* w */
3830 { "oslsr_el1", CPENC(2,0,C1, C1, 4), 0 }, /* r */
3831 { "osdlr_el1", CPENC(2,0,C1, C3, 4), 0 },
3832 { "dbgprcr_el1", CPENC(2,0,C1, C4, 4), 0 },
3833 { "dbgclaimset_el1", CPENC(2,0,C7, C8, 6), 0 },
3834 { "dbgclaimclr_el1", CPENC(2,0,C7, C9, 6), 0 },
3835 { "dbgauthstatus_el1", CPENC(2,0,C7, C14,6), 0 }, /* r */
55c144e6
MW
3836 { "pmblimitr_el1", CPENC (3, 0, C9, C10, 0), F_ARCHEXT }, /* rw */
3837 { "pmbptr_el1", CPENC (3, 0, C9, C10, 1), F_ARCHEXT }, /* rw */
3838 { "pmbsr_el1", CPENC (3, 0, C9, C10, 3), F_ARCHEXT }, /* rw */
3839 { "pmbidr_el1", CPENC (3, 0, C9, C10, 7), F_ARCHEXT }, /* ro */
3840 { "pmscr_el1", CPENC (3, 0, C9, C9, 0), F_ARCHEXT }, /* rw */
3841 { "pmsicr_el1", CPENC (3, 0, C9, C9, 2), F_ARCHEXT }, /* rw */
3842 { "pmsirr_el1", CPENC (3, 0, C9, C9, 3), F_ARCHEXT }, /* rw */
3843 { "pmsfcr_el1", CPENC (3, 0, C9, C9, 4), F_ARCHEXT }, /* rw */
3844 { "pmsevfr_el1", CPENC (3, 0, C9, C9, 5), F_ARCHEXT }, /* rw */
3845 { "pmslatfr_el1", CPENC (3, 0, C9, C9, 6), F_ARCHEXT }, /* rw */
3846 { "pmsidr_el1", CPENC (3, 0, C9, C9, 7), F_ARCHEXT }, /* ro */
3847 { "pmscr_el2", CPENC (3, 4, C9, C9, 0), F_ARCHEXT }, /* rw */
3848 { "pmscr_el12", CPENC (3, 5, C9, C9, 0), F_ARCHEXT }, /* rw */
49eec193
YZ
3849 { "pmcr_el0", CPENC(3,3,C9,C12, 0), 0 },
3850 { "pmcntenset_el0", CPENC(3,3,C9,C12, 1), 0 },
3851 { "pmcntenclr_el0", CPENC(3,3,C9,C12, 2), 0 },
3852 { "pmovsclr_el0", CPENC(3,3,C9,C12, 3), 0 },
3853 { "pmswinc_el0", CPENC(3,3,C9,C12, 4), 0 }, /* w */
3854 { "pmselr_el0", CPENC(3,3,C9,C12, 5), 0 },
3855 { "pmceid0_el0", CPENC(3,3,C9,C12, 6), 0 }, /* r */
3856 { "pmceid1_el0", CPENC(3,3,C9,C12, 7), 0 }, /* r */
3857 { "pmccntr_el0", CPENC(3,3,C9,C13, 0), 0 },
3858 { "pmxevtyper_el0", CPENC(3,3,C9,C13, 1), 0 },
3859 { "pmxevcntr_el0", CPENC(3,3,C9,C13, 2), 0 },
3860 { "pmuserenr_el0", CPENC(3,3,C9,C14, 0), 0 },
3861 { "pmintenset_el1", CPENC(3,0,C9,C14, 1), 0 },
3862 { "pmintenclr_el1", CPENC(3,0,C9,C14, 2), 0 },
3863 { "pmovsset_el0", CPENC(3,3,C9,C14, 3), 0 },
3864 { "pmevcntr0_el0", CPENC(3,3,C14,C8, 0), 0 },
3865 { "pmevcntr1_el0", CPENC(3,3,C14,C8, 1), 0 },
3866 { "pmevcntr2_el0", CPENC(3,3,C14,C8, 2), 0 },
3867 { "pmevcntr3_el0", CPENC(3,3,C14,C8, 3), 0 },
3868 { "pmevcntr4_el0", CPENC(3,3,C14,C8, 4), 0 },
3869 { "pmevcntr5_el0", CPENC(3,3,C14,C8, 5), 0 },
3870 { "pmevcntr6_el0", CPENC(3,3,C14,C8, 6), 0 },
3871 { "pmevcntr7_el0", CPENC(3,3,C14,C8, 7), 0 },
3872 { "pmevcntr8_el0", CPENC(3,3,C14,C9, 0), 0 },
3873 { "pmevcntr9_el0", CPENC(3,3,C14,C9, 1), 0 },
3874 { "pmevcntr10_el0", CPENC(3,3,C14,C9, 2), 0 },
3875 { "pmevcntr11_el0", CPENC(3,3,C14,C9, 3), 0 },
3876 { "pmevcntr12_el0", CPENC(3,3,C14,C9, 4), 0 },
3877 { "pmevcntr13_el0", CPENC(3,3,C14,C9, 5), 0 },
3878 { "pmevcntr14_el0", CPENC(3,3,C14,C9, 6), 0 },
3879 { "pmevcntr15_el0", CPENC(3,3,C14,C9, 7), 0 },
3880 { "pmevcntr16_el0", CPENC(3,3,C14,C10,0), 0 },
3881 { "pmevcntr17_el0", CPENC(3,3,C14,C10,1), 0 },
3882 { "pmevcntr18_el0", CPENC(3,3,C14,C10,2), 0 },
3883 { "pmevcntr19_el0", CPENC(3,3,C14,C10,3), 0 },
3884 { "pmevcntr20_el0", CPENC(3,3,C14,C10,4), 0 },
3885 { "pmevcntr21_el0", CPENC(3,3,C14,C10,5), 0 },
3886 { "pmevcntr22_el0", CPENC(3,3,C14,C10,6), 0 },
3887 { "pmevcntr23_el0", CPENC(3,3,C14,C10,7), 0 },
3888 { "pmevcntr24_el0", CPENC(3,3,C14,C11,0), 0 },
3889 { "pmevcntr25_el0", CPENC(3,3,C14,C11,1), 0 },
3890 { "pmevcntr26_el0", CPENC(3,3,C14,C11,2), 0 },
3891 { "pmevcntr27_el0", CPENC(3,3,C14,C11,3), 0 },
3892 { "pmevcntr28_el0", CPENC(3,3,C14,C11,4), 0 },
3893 { "pmevcntr29_el0", CPENC(3,3,C14,C11,5), 0 },
3894 { "pmevcntr30_el0", CPENC(3,3,C14,C11,6), 0 },
3895 { "pmevtyper0_el0", CPENC(3,3,C14,C12,0), 0 },
3896 { "pmevtyper1_el0", CPENC(3,3,C14,C12,1), 0 },
3897 { "pmevtyper2_el0", CPENC(3,3,C14,C12,2), 0 },
3898 { "pmevtyper3_el0", CPENC(3,3,C14,C12,3), 0 },
3899 { "pmevtyper4_el0", CPENC(3,3,C14,C12,4), 0 },
3900 { "pmevtyper5_el0", CPENC(3,3,C14,C12,5), 0 },
3901 { "pmevtyper6_el0", CPENC(3,3,C14,C12,6), 0 },
3902 { "pmevtyper7_el0", CPENC(3,3,C14,C12,7), 0 },
3903 { "pmevtyper8_el0", CPENC(3,3,C14,C13,0), 0 },
3904 { "pmevtyper9_el0", CPENC(3,3,C14,C13,1), 0 },
3905 { "pmevtyper10_el0", CPENC(3,3,C14,C13,2), 0 },
3906 { "pmevtyper11_el0", CPENC(3,3,C14,C13,3), 0 },
3907 { "pmevtyper12_el0", CPENC(3,3,C14,C13,4), 0 },
3908 { "pmevtyper13_el0", CPENC(3,3,C14,C13,5), 0 },
3909 { "pmevtyper14_el0", CPENC(3,3,C14,C13,6), 0 },
3910 { "pmevtyper15_el0", CPENC(3,3,C14,C13,7), 0 },
3911 { "pmevtyper16_el0", CPENC(3,3,C14,C14,0), 0 },
3912 { "pmevtyper17_el0", CPENC(3,3,C14,C14,1), 0 },
3913 { "pmevtyper18_el0", CPENC(3,3,C14,C14,2), 0 },
3914 { "pmevtyper19_el0", CPENC(3,3,C14,C14,3), 0 },
3915 { "pmevtyper20_el0", CPENC(3,3,C14,C14,4), 0 },
3916 { "pmevtyper21_el0", CPENC(3,3,C14,C14,5), 0 },
3917 { "pmevtyper22_el0", CPENC(3,3,C14,C14,6), 0 },
3918 { "pmevtyper23_el0", CPENC(3,3,C14,C14,7), 0 },
3919 { "pmevtyper24_el0", CPENC(3,3,C14,C15,0), 0 },
3920 { "pmevtyper25_el0", CPENC(3,3,C14,C15,1), 0 },
3921 { "pmevtyper26_el0", CPENC(3,3,C14,C15,2), 0 },
3922 { "pmevtyper27_el0", CPENC(3,3,C14,C15,3), 0 },
3923 { "pmevtyper28_el0", CPENC(3,3,C14,C15,4), 0 },
3924 { "pmevtyper29_el0", CPENC(3,3,C14,C15,5), 0 },
3925 { "pmevtyper30_el0", CPENC(3,3,C14,C15,6), 0 },
3926 { "pmccfiltr_el0", CPENC(3,3,C14,C15,7), 0 },
3927 { 0, CPENC(0,0,0,0,0), 0 },
a06ea964
NC
3928};
3929
49eec193
YZ
3930bfd_boolean
3931aarch64_sys_reg_deprecated_p (const aarch64_sys_reg *reg)
3932{
3933 return (reg->flags & F_DEPRECATED) != 0;
3934}
3935
f21cce2c
MW
3936bfd_boolean
3937aarch64_sys_reg_supported_p (const aarch64_feature_set features,
3938 const aarch64_sys_reg *reg)
3939{
3940 if (!(reg->flags & F_ARCHEXT))
3941 return TRUE;
3942
3943 /* PAN. Values are from aarch64_sys_regs. */
3944 if (reg->value == CPEN_(0,C2,3)
3945 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_PAN))
3946 return FALSE;
3947
250aafa4
MW
3948 /* Virtualization host extensions: system registers. */
3949 if ((reg->value == CPENC (3, 4, C2, C0, 1)
3950 || reg->value == CPENC (3, 4, C13, C0, 1)
3951 || reg->value == CPENC (3, 4, C14, C3, 0)
3952 || reg->value == CPENC (3, 4, C14, C3, 1)
3953 || reg->value == CPENC (3, 4, C14, C3, 2))
3954 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_1))
3955 return FALSE;
3956
3957 /* Virtualization host extensions: *_el12 names of *_el1 registers. */
3958 if ((reg->value == CPEN_ (5, C0, 0)
3959 || reg->value == CPEN_ (5, C0, 1)
3960 || reg->value == CPENC (3, 5, C1, C0, 0)
3961 || reg->value == CPENC (3, 5, C1, C0, 2)
3962 || reg->value == CPENC (3, 5, C2, C0, 0)
3963 || reg->value == CPENC (3, 5, C2, C0, 1)
3964 || reg->value == CPENC (3, 5, C2, C0, 2)
3965 || reg->value == CPENC (3, 5, C5, C1, 0)
3966 || reg->value == CPENC (3, 5, C5, C1, 1)
3967 || reg->value == CPENC (3, 5, C5, C2, 0)
3968 || reg->value == CPENC (3, 5, C6, C0, 0)
3969 || reg->value == CPENC (3, 5, C10, C2, 0)
3970 || reg->value == CPENC (3, 5, C10, C3, 0)
3971 || reg->value == CPENC (3, 5, C12, C0, 0)
3972 || reg->value == CPENC (3, 5, C13, C0, 1)
3973 || reg->value == CPENC (3, 5, C14, C1, 0))
3974 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_1))
3975 return FALSE;
3976
3977 /* Virtualization host extensions: *_el02 names of *_el0 registers. */
3978 if ((reg->value == CPENC (3, 5, C14, C2, 0)
3979 || reg->value == CPENC (3, 5, C14, C2, 1)
3980 || reg->value == CPENC (3, 5, C14, C2, 2)
3981 || reg->value == CPENC (3, 5, C14, C3, 0)
3982 || reg->value == CPENC (3, 5, C14, C3, 1)
3983 || reg->value == CPENC (3, 5, C14, C3, 2))
3984 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_1))
63511907 3985 return FALSE;
1a04d1a7
MW
3986
3987 /* ARMv8.2 features. */
6479e48e
MW
3988
3989 /* ID_AA64MMFR2_EL1. */
1a04d1a7
MW
3990 if (reg->value == CPENC (3, 0, C0, C7, 2)
3991 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
250aafa4
MW
3992 return FALSE;
3993
6479e48e
MW
3994 /* PSTATE.UAO. */
3995 if (reg->value == CPEN_ (0, C2, 4)
3996 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
3997 return FALSE;
3998
47f81142
MW
3999 /* RAS extension. */
4000
651657fa
MW
4001 /* ERRIDR_EL1, ERRSELR_EL1, ERXFR_EL1, ERXCTLR_EL1, ERXSTATUS_EL, ERXADDR_EL1,
4002 ERXMISC0_EL1 AND ERXMISC1_EL1. */
47f81142 4003 if ((reg->value == CPENC (3, 0, C5, C3, 0)
651657fa 4004 || reg->value == CPENC (3, 0, C5, C3, 1)
47f81142
MW
4005 || reg->value == CPENC (3, 0, C5, C3, 2)
4006 || reg->value == CPENC (3, 0, C5, C3, 3)
651657fa
MW
4007 || reg->value == CPENC (3, 0, C5, C4, 0)
4008 || reg->value == CPENC (3, 0, C5, C4, 1)
4009 || reg->value == CPENC (3, 0, C5, C4, 2)
4010 || reg->value == CPENC (3, 0, C5, C4, 3)
47f81142
MW
4011 || reg->value == CPENC (3, 0, C5, C5, 0)
4012 || reg->value == CPENC (3, 0, C5, C5, 1))
4013 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_RAS))
4014 return FALSE;
4015
4016 /* VSESR_EL2, DISR_EL1 and VDISR_EL2. */
4017 if ((reg->value == CPENC (3, 4, C5, C2, 3)
4018 || reg->value == CPENC (3, 0, C12, C1, 1)
4019 || reg->value == CPENC (3, 4, C12, C1, 1))
4020 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_RAS))
4021 return FALSE;
4022
55c144e6
MW
4023 /* Statistical Profiling extension. */
4024 if ((reg->value == CPENC (3, 0, C9, C10, 0)
4025 || reg->value == CPENC (3, 0, C9, C10, 1)
4026 || reg->value == CPENC (3, 0, C9, C10, 3)
4027 || reg->value == CPENC (3, 0, C9, C10, 7)
4028 || reg->value == CPENC (3, 0, C9, C9, 0)
4029 || reg->value == CPENC (3, 0, C9, C9, 2)
4030 || reg->value == CPENC (3, 0, C9, C9, 3)
4031 || reg->value == CPENC (3, 0, C9, C9, 4)
4032 || reg->value == CPENC (3, 0, C9, C9, 5)
4033 || reg->value == CPENC (3, 0, C9, C9, 6)
4034 || reg->value == CPENC (3, 0, C9, C9, 7)
4035 || reg->value == CPENC (3, 4, C9, C9, 0)
4036 || reg->value == CPENC (3, 5, C9, C9, 0))
4037 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_PROFILE))
4038 return FALSE;
4039
b0bfa7b5
SN
4040 /* ARMv8.3 Pointer authentication keys. */
4041 if ((reg->value == CPENC (3, 0, C2, C1, 0)
4042 || reg->value == CPENC (3, 0, C2, C1, 1)
4043 || reg->value == CPENC (3, 0, C2, C1, 2)
4044 || reg->value == CPENC (3, 0, C2, C1, 3)
4045 || reg->value == CPENC (3, 0, C2, C2, 0)
4046 || reg->value == CPENC (3, 0, C2, C2, 1)
4047 || reg->value == CPENC (3, 0, C2, C2, 2)
4048 || reg->value == CPENC (3, 0, C2, C2, 3)
4049 || reg->value == CPENC (3, 0, C2, C3, 0)
4050 || reg->value == CPENC (3, 0, C2, C3, 1))
4051 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_3))
4052 return FALSE;
4053
f21cce2c
MW
4054 return TRUE;
4055}
4056
87b8eed7 4057const aarch64_sys_reg aarch64_pstatefields [] =
a06ea964 4058{
87b8eed7
YZ
4059 { "spsel", 0x05, 0 },
4060 { "daifset", 0x1e, 0 },
4061 { "daifclr", 0x1f, 0 },
f21cce2c 4062 { "pan", 0x04, F_ARCHEXT },
6479e48e 4063 { "uao", 0x03, F_ARCHEXT },
87b8eed7 4064 { 0, CPENC(0,0,0,0,0), 0 },
a06ea964
NC
4065};
4066
f21cce2c
MW
4067bfd_boolean
4068aarch64_pstatefield_supported_p (const aarch64_feature_set features,
4069 const aarch64_sys_reg *reg)
4070{
4071 if (!(reg->flags & F_ARCHEXT))
4072 return TRUE;
4073
4074 /* PAN. Values are from aarch64_pstatefields. */
4075 if (reg->value == 0x04
4076 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_PAN))
4077 return FALSE;
4078
6479e48e
MW
4079 /* UAO. Values are from aarch64_pstatefields. */
4080 if (reg->value == 0x03
4081 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
4082 return FALSE;
4083
f21cce2c
MW
4084 return TRUE;
4085}
4086
a06ea964
NC
4087const aarch64_sys_ins_reg aarch64_sys_regs_ic[] =
4088{
4089 { "ialluis", CPENS(0,C7,C1,0), 0 },
4090 { "iallu", CPENS(0,C7,C5,0), 0 },
ea2deeec 4091 { "ivau", CPENS (3, C7, C5, 1), F_HASXT },
a06ea964
NC
4092 { 0, CPENS(0,0,0,0), 0 }
4093};
4094
4095const aarch64_sys_ins_reg aarch64_sys_regs_dc[] =
4096{
ea2deeec
MW
4097 { "zva", CPENS (3, C7, C4, 1), F_HASXT },
4098 { "ivac", CPENS (0, C7, C6, 1), F_HASXT },
4099 { "isw", CPENS (0, C7, C6, 2), F_HASXT },
4100 { "cvac", CPENS (3, C7, C10, 1), F_HASXT },
4101 { "csw", CPENS (0, C7, C10, 2), F_HASXT },
4102 { "cvau", CPENS (3, C7, C11, 1), F_HASXT },
d6bf7ce6 4103 { "cvap", CPENS (3, C7, C12, 1), F_HASXT | F_ARCHEXT },
ea2deeec
MW
4104 { "civac", CPENS (3, C7, C14, 1), F_HASXT },
4105 { "cisw", CPENS (0, C7, C14, 2), F_HASXT },
a06ea964
NC
4106 { 0, CPENS(0,0,0,0), 0 }
4107};
4108
4109const aarch64_sys_ins_reg aarch64_sys_regs_at[] =
4110{
ea2deeec
MW
4111 { "s1e1r", CPENS (0, C7, C8, 0), F_HASXT },
4112 { "s1e1w", CPENS (0, C7, C8, 1), F_HASXT },
4113 { "s1e0r", CPENS (0, C7, C8, 2), F_HASXT },
4114 { "s1e0w", CPENS (0, C7, C8, 3), F_HASXT },
4115 { "s12e1r", CPENS (4, C7, C8, 4), F_HASXT },
4116 { "s12e1w", CPENS (4, C7, C8, 5), F_HASXT },
4117 { "s12e0r", CPENS (4, C7, C8, 6), F_HASXT },
4118 { "s12e0w", CPENS (4, C7, C8, 7), F_HASXT },
4119 { "s1e2r", CPENS (4, C7, C8, 0), F_HASXT },
4120 { "s1e2w", CPENS (4, C7, C8, 1), F_HASXT },
4121 { "s1e3r", CPENS (6, C7, C8, 0), F_HASXT },
4122 { "s1e3w", CPENS (6, C7, C8, 1), F_HASXT },
22a5455c
MW
4123 { "s1e1rp", CPENS (0, C7, C9, 0), F_HASXT | F_ARCHEXT },
4124 { "s1e1wp", CPENS (0, C7, C9, 1), F_HASXT | F_ARCHEXT },
a06ea964
NC
4125 { 0, CPENS(0,0,0,0), 0 }
4126};
4127
4128const aarch64_sys_ins_reg aarch64_sys_regs_tlbi[] =
4129{
4130 { "vmalle1", CPENS(0,C8,C7,0), 0 },
ea2deeec
MW
4131 { "vae1", CPENS (0, C8, C7, 1), F_HASXT },
4132 { "aside1", CPENS (0, C8, C7, 2), F_HASXT },
4133 { "vaae1", CPENS (0, C8, C7, 3), F_HASXT },
a06ea964 4134 { "vmalle1is", CPENS(0,C8,C3,0), 0 },
ea2deeec
MW
4135 { "vae1is", CPENS (0, C8, C3, 1), F_HASXT },
4136 { "aside1is", CPENS (0, C8, C3, 2), F_HASXT },
4137 { "vaae1is", CPENS (0, C8, C3, 3), F_HASXT },
4138 { "ipas2e1is", CPENS (4, C8, C0, 1), F_HASXT },
4139 { "ipas2le1is",CPENS (4, C8, C0, 5), F_HASXT },
4140 { "ipas2e1", CPENS (4, C8, C4, 1), F_HASXT },
4141 { "ipas2le1", CPENS (4, C8, C4, 5), F_HASXT },
4142 { "vae2", CPENS (4, C8, C7, 1), F_HASXT },
4143 { "vae2is", CPENS (4, C8, C3, 1), F_HASXT },
a06ea964
NC
4144 { "vmalls12e1",CPENS(4,C8,C7,6), 0 },
4145 { "vmalls12e1is",CPENS(4,C8,C3,6), 0 },
ea2deeec
MW
4146 { "vae3", CPENS (6, C8, C7, 1), F_HASXT },
4147 { "vae3is", CPENS (6, C8, C3, 1), F_HASXT },
a06ea964
NC
4148 { "alle2", CPENS(4,C8,C7,0), 0 },
4149 { "alle2is", CPENS(4,C8,C3,0), 0 },
4150 { "alle1", CPENS(4,C8,C7,4), 0 },
4151 { "alle1is", CPENS(4,C8,C3,4), 0 },
4152 { "alle3", CPENS(6,C8,C7,0), 0 },
4153 { "alle3is", CPENS(6,C8,C3,0), 0 },
ea2deeec
MW
4154 { "vale1is", CPENS (0, C8, C3, 5), F_HASXT },
4155 { "vale2is", CPENS (4, C8, C3, 5), F_HASXT },
4156 { "vale3is", CPENS (6, C8, C3, 5), F_HASXT },
4157 { "vaale1is", CPENS (0, C8, C3, 7), F_HASXT },
4158 { "vale1", CPENS (0, C8, C7, 5), F_HASXT },
4159 { "vale2", CPENS (4, C8, C7, 5), F_HASXT },
4160 { "vale3", CPENS (6, C8, C7, 5), F_HASXT },
4161 { "vaale1", CPENS (0, C8, C7, 7), F_HASXT },
a06ea964
NC
4162 { 0, CPENS(0,0,0,0), 0 }
4163};
4164
ea2deeec
MW
4165bfd_boolean
4166aarch64_sys_ins_reg_has_xt (const aarch64_sys_ins_reg *sys_ins_reg)
4167{
4168 return (sys_ins_reg->flags & F_HASXT) != 0;
4169}
4170
d6bf7ce6
MW
4171extern bfd_boolean
4172aarch64_sys_ins_reg_supported_p (const aarch64_feature_set features,
4173 const aarch64_sys_ins_reg *reg)
4174{
4175 if (!(reg->flags & F_ARCHEXT))
4176 return TRUE;
4177
4178 /* DC CVAP. Values are from aarch64_sys_regs_dc. */
4179 if (reg->value == CPENS (3, C7, C12, 1)
4180 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
4181 return FALSE;
4182
63511907
MW
4183 /* AT S1E1RP, AT S1E1WP. Values are from aarch64_sys_regs_at. */
4184 if ((reg->value == CPENS (0, C7, C9, 0)
4185 || reg->value == CPENS (0, C7, C9, 1))
4186 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
4187 return FALSE;
4188
d6bf7ce6
MW
4189 return TRUE;
4190}
4191
a06ea964
NC
4192#undef C0
4193#undef C1
4194#undef C2
4195#undef C3
4196#undef C4
4197#undef C5
4198#undef C6
4199#undef C7
4200#undef C8
4201#undef C9
4202#undef C10
4203#undef C11
4204#undef C12
4205#undef C13
4206#undef C14
4207#undef C15
4208
4bd13cde
NC
4209#define BIT(INSN,BT) (((INSN) >> (BT)) & 1)
4210#define BITS(INSN,HI,LO) (((INSN) >> (LO)) & ((1 << (((HI) - (LO)) + 1)) - 1))
4211
20f55f38 4212static bfd_boolean
4bd13cde
NC
4213verify_ldpsw (const struct aarch64_opcode * opcode ATTRIBUTE_UNUSED,
4214 const aarch64_insn insn)
4215{
4216 int t = BITS (insn, 4, 0);
4217 int n = BITS (insn, 9, 5);
4218 int t2 = BITS (insn, 14, 10);
4219
4220 if (BIT (insn, 23))
4221 {
4222 /* Write back enabled. */
4223 if ((t == n || t2 == n) && n != 31)
4224 return FALSE;
4225 }
4226
4227 if (BIT (insn, 22))
4228 {
4229 /* Load */
4230 if (t == t2)
4231 return FALSE;
4232 }
4233
4234 return TRUE;
4235}
4236
e950b345
RS
4237/* Return true if VALUE cannot be moved into an SVE register using DUP
4238 (with any element size, not just ESIZE) and if using DUPM would
4239 therefore be OK. ESIZE is the number of bytes in the immediate. */
4240
4241bfd_boolean
4242aarch64_sve_dupm_mov_immediate_p (uint64_t uvalue, int esize)
4243{
4244 int64_t svalue = uvalue;
4245 uint64_t upper = (uint64_t) -1 << (esize * 4) << (esize * 4);
4246
4247 if ((uvalue & ~upper) != uvalue && (uvalue | upper) != uvalue)
4248 return FALSE;
4249 if (esize <= 4 || (uint32_t) uvalue == (uint32_t) (uvalue >> 32))
4250 {
4251 svalue = (int32_t) uvalue;
4252 if (esize <= 2 || (uint16_t) uvalue == (uint16_t) (uvalue >> 16))
4253 {
4254 svalue = (int16_t) uvalue;
4255 if (esize == 1 || (uint8_t) uvalue == (uint8_t) (uvalue >> 8))
4256 return FALSE;
4257 }
4258 }
4259 if ((svalue & 0xff) == 0)
4260 svalue /= 256;
4261 return svalue < -128 || svalue >= 128;
4262}
4263
a06ea964
NC
4264/* Include the opcode description table as well as the operand description
4265 table. */
20f55f38 4266#define VERIFIER(x) verify_##x
a06ea964 4267#include "aarch64-tbl.h"
This page took 0.434623 seconds and 4 git commands to generate.