[AArch64] Add ARMv8.3 instructions which are in the NOP space
[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:
a06ea964
NC
2992 assert (opnd->qualifier == AARCH64_OPND_QLF_W
2993 || opnd->qualifier == AARCH64_OPND_QLF_WSP
2994 || opnd->qualifier == AARCH64_OPND_QLF_X
2995 || opnd->qualifier == AARCH64_OPND_QLF_SP);
2996 snprintf (buf, size, "%s",
2997 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 1));
2998 break;
2999
3000 case AARCH64_OPND_Rm_EXT:
3001 kind = opnd->shifter.kind;
3002 assert (idx == 1 || idx == 2);
3003 if ((aarch64_stack_pointer_p (opnds)
3004 || (idx == 2 && aarch64_stack_pointer_p (opnds + 1)))
3005 && ((opnd->qualifier == AARCH64_OPND_QLF_W
3006 && opnds[0].qualifier == AARCH64_OPND_QLF_W
3007 && kind == AARCH64_MOD_UXTW)
3008 || (opnd->qualifier == AARCH64_OPND_QLF_X
3009 && kind == AARCH64_MOD_UXTX)))
3010 {
3011 /* 'LSL' is the preferred form in this case. */
3012 kind = AARCH64_MOD_LSL;
3013 if (opnd->shifter.amount == 0)
3014 {
3015 /* Shifter omitted. */
3016 snprintf (buf, size, "%s",
3017 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
3018 break;
3019 }
3020 }
3021 if (opnd->shifter.amount)
2442d846 3022 snprintf (buf, size, "%s, %s #%" PRIi64,
a06ea964
NC
3023 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
3024 aarch64_operand_modifiers[kind].name,
3025 opnd->shifter.amount);
3026 else
3027 snprintf (buf, size, "%s, %s",
3028 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
3029 aarch64_operand_modifiers[kind].name);
3030 break;
3031
3032 case AARCH64_OPND_Rm_SFT:
3033 assert (opnd->qualifier == AARCH64_OPND_QLF_W
3034 || opnd->qualifier == AARCH64_OPND_QLF_X);
3035 if (opnd->shifter.amount == 0 && opnd->shifter.kind == AARCH64_MOD_LSL)
3036 snprintf (buf, size, "%s",
3037 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
3038 else
2442d846 3039 snprintf (buf, size, "%s, %s #%" PRIi64,
a06ea964
NC
3040 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
3041 aarch64_operand_modifiers[opnd->shifter.kind].name,
3042 opnd->shifter.amount);
3043 break;
3044
3045 case AARCH64_OPND_Fd:
3046 case AARCH64_OPND_Fn:
3047 case AARCH64_OPND_Fm:
3048 case AARCH64_OPND_Fa:
3049 case AARCH64_OPND_Ft:
3050 case AARCH64_OPND_Ft2:
3051 case AARCH64_OPND_Sd:
3052 case AARCH64_OPND_Sn:
3053 case AARCH64_OPND_Sm:
047cd301
RS
3054 case AARCH64_OPND_SVE_VZn:
3055 case AARCH64_OPND_SVE_Vd:
3056 case AARCH64_OPND_SVE_Vm:
3057 case AARCH64_OPND_SVE_Vn:
a06ea964
NC
3058 snprintf (buf, size, "%s%d", aarch64_get_qualifier_name (opnd->qualifier),
3059 opnd->reg.regno);
3060 break;
3061
3062 case AARCH64_OPND_Vd:
3063 case AARCH64_OPND_Vn:
3064 case AARCH64_OPND_Vm:
3065 snprintf (buf, size, "v%d.%s", opnd->reg.regno,
3066 aarch64_get_qualifier_name (opnd->qualifier));
3067 break;
3068
3069 case AARCH64_OPND_Ed:
3070 case AARCH64_OPND_En:
3071 case AARCH64_OPND_Em:
dab26bf4 3072 snprintf (buf, size, "v%d.%s[%" PRIi64 "]", opnd->reglane.regno,
a06ea964
NC
3073 aarch64_get_qualifier_name (opnd->qualifier),
3074 opnd->reglane.index);
3075 break;
3076
3077 case AARCH64_OPND_VdD1:
3078 case AARCH64_OPND_VnD1:
3079 snprintf (buf, size, "v%d.d[1]", opnd->reg.regno);
3080 break;
3081
3082 case AARCH64_OPND_LVn:
3083 case AARCH64_OPND_LVt:
3084 case AARCH64_OPND_LVt_AL:
3085 case AARCH64_OPND_LEt:
8a7f0c1b 3086 print_register_list (buf, size, opnd, "v");
a06ea964
NC
3087 break;
3088
f11ad6bc
RS
3089 case AARCH64_OPND_SVE_Pd:
3090 case AARCH64_OPND_SVE_Pg3:
3091 case AARCH64_OPND_SVE_Pg4_5:
3092 case AARCH64_OPND_SVE_Pg4_10:
3093 case AARCH64_OPND_SVE_Pg4_16:
3094 case AARCH64_OPND_SVE_Pm:
3095 case AARCH64_OPND_SVE_Pn:
3096 case AARCH64_OPND_SVE_Pt:
3097 if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
3098 snprintf (buf, size, "p%d", opnd->reg.regno);
d50c751e
RS
3099 else if (opnd->qualifier == AARCH64_OPND_QLF_P_Z
3100 || opnd->qualifier == AARCH64_OPND_QLF_P_M)
3101 snprintf (buf, size, "p%d/%s", opnd->reg.regno,
3102 aarch64_get_qualifier_name (opnd->qualifier));
f11ad6bc
RS
3103 else
3104 snprintf (buf, size, "p%d.%s", opnd->reg.regno,
3105 aarch64_get_qualifier_name (opnd->qualifier));
3106 break;
3107
3108 case AARCH64_OPND_SVE_Za_5:
3109 case AARCH64_OPND_SVE_Za_16:
3110 case AARCH64_OPND_SVE_Zd:
3111 case AARCH64_OPND_SVE_Zm_5:
3112 case AARCH64_OPND_SVE_Zm_16:
3113 case AARCH64_OPND_SVE_Zn:
3114 case AARCH64_OPND_SVE_Zt:
3115 if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
3116 snprintf (buf, size, "z%d", opnd->reg.regno);
3117 else
3118 snprintf (buf, size, "z%d.%s", opnd->reg.regno,
3119 aarch64_get_qualifier_name (opnd->qualifier));
3120 break;
3121
3122 case AARCH64_OPND_SVE_ZnxN:
3123 case AARCH64_OPND_SVE_ZtxN:
3124 print_register_list (buf, size, opnd, "z");
3125 break;
3126
3127 case AARCH64_OPND_SVE_Zn_INDEX:
3128 snprintf (buf, size, "z%d.%s[%" PRIi64 "]", opnd->reglane.regno,
3129 aarch64_get_qualifier_name (opnd->qualifier),
3130 opnd->reglane.index);
3131 break;
3132
a06ea964
NC
3133 case AARCH64_OPND_Cn:
3134 case AARCH64_OPND_Cm:
3135 snprintf (buf, size, "C%d", opnd->reg.regno);
3136 break;
3137
3138 case AARCH64_OPND_IDX:
3139 case AARCH64_OPND_IMM:
3140 case AARCH64_OPND_WIDTH:
3141 case AARCH64_OPND_UIMM3_OP1:
3142 case AARCH64_OPND_UIMM3_OP2:
3143 case AARCH64_OPND_BIT_NUM:
3144 case AARCH64_OPND_IMM_VLSL:
3145 case AARCH64_OPND_IMM_VLSR:
3146 case AARCH64_OPND_SHLL_IMM:
3147 case AARCH64_OPND_IMM0:
3148 case AARCH64_OPND_IMMR:
3149 case AARCH64_OPND_IMMS:
3150 case AARCH64_OPND_FBITS:
e950b345
RS
3151 case AARCH64_OPND_SIMM5:
3152 case AARCH64_OPND_SVE_SHLIMM_PRED:
3153 case AARCH64_OPND_SVE_SHLIMM_UNPRED:
3154 case AARCH64_OPND_SVE_SHRIMM_PRED:
3155 case AARCH64_OPND_SVE_SHRIMM_UNPRED:
3156 case AARCH64_OPND_SVE_SIMM5:
3157 case AARCH64_OPND_SVE_SIMM5B:
3158 case AARCH64_OPND_SVE_SIMM6:
3159 case AARCH64_OPND_SVE_SIMM8:
3160 case AARCH64_OPND_SVE_UIMM3:
3161 case AARCH64_OPND_SVE_UIMM7:
3162 case AARCH64_OPND_SVE_UIMM8:
3163 case AARCH64_OPND_SVE_UIMM8_53:
a06ea964
NC
3164 snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
3165 break;
3166
165d4950
RS
3167 case AARCH64_OPND_SVE_I1_HALF_ONE:
3168 case AARCH64_OPND_SVE_I1_HALF_TWO:
3169 case AARCH64_OPND_SVE_I1_ZERO_ONE:
3170 {
3171 single_conv_t c;
3172 c.i = opnd->imm.value;
3173 snprintf (buf, size, "#%.1f", c.f);
3174 break;
3175 }
3176
245d2e3f
RS
3177 case AARCH64_OPND_SVE_PATTERN:
3178 if (optional_operand_p (opcode, idx)
3179 && opnd->imm.value == get_optional_operand_default_value (opcode))
3180 break;
3181 enum_value = opnd->imm.value;
3182 assert (enum_value < ARRAY_SIZE (aarch64_sve_pattern_array));
3183 if (aarch64_sve_pattern_array[enum_value])
3184 snprintf (buf, size, "%s", aarch64_sve_pattern_array[enum_value]);
3185 else
3186 snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
3187 break;
3188
2442d846
RS
3189 case AARCH64_OPND_SVE_PATTERN_SCALED:
3190 if (optional_operand_p (opcode, idx)
3191 && !opnd->shifter.operator_present
3192 && opnd->imm.value == get_optional_operand_default_value (opcode))
3193 break;
3194 enum_value = opnd->imm.value;
3195 assert (enum_value < ARRAY_SIZE (aarch64_sve_pattern_array));
3196 if (aarch64_sve_pattern_array[opnd->imm.value])
3197 snprintf (buf, size, "%s", aarch64_sve_pattern_array[opnd->imm.value]);
3198 else
3199 snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
3200 if (opnd->shifter.operator_present)
3201 {
3202 size_t len = strlen (buf);
3203 snprintf (buf + len, size - len, ", %s #%" PRIi64,
3204 aarch64_operand_modifiers[opnd->shifter.kind].name,
3205 opnd->shifter.amount);
3206 }
3207 break;
3208
245d2e3f
RS
3209 case AARCH64_OPND_SVE_PRFOP:
3210 enum_value = opnd->imm.value;
3211 assert (enum_value < ARRAY_SIZE (aarch64_sve_prfop_array));
3212 if (aarch64_sve_prfop_array[enum_value])
3213 snprintf (buf, size, "%s", aarch64_sve_prfop_array[enum_value]);
3214 else
3215 snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
3216 break;
3217
fb098a1e
YZ
3218 case AARCH64_OPND_IMM_MOV:
3219 switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
3220 {
3221 case 4: /* e.g. MOV Wd, #<imm32>. */
3222 {
3223 int imm32 = opnd->imm.value;
3224 snprintf (buf, size, "#0x%-20x\t// #%d", imm32, imm32);
3225 }
3226 break;
3227 case 8: /* e.g. MOV Xd, #<imm64>. */
3228 snprintf (buf, size, "#0x%-20" PRIx64 "\t// #%" PRIi64,
3229 opnd->imm.value, opnd->imm.value);
3230 break;
3231 default: assert (0);
3232 }
3233 break;
3234
a06ea964
NC
3235 case AARCH64_OPND_FPIMM0:
3236 snprintf (buf, size, "#0.0");
3237 break;
3238
3239 case AARCH64_OPND_LIMM:
3240 case AARCH64_OPND_AIMM:
3241 case AARCH64_OPND_HALF:
e950b345
RS
3242 case AARCH64_OPND_SVE_INV_LIMM:
3243 case AARCH64_OPND_SVE_LIMM:
3244 case AARCH64_OPND_SVE_LIMM_MOV:
a06ea964 3245 if (opnd->shifter.amount)
2442d846 3246 snprintf (buf, size, "#0x%" PRIx64 ", lsl #%" PRIi64, opnd->imm.value,
a06ea964
NC
3247 opnd->shifter.amount);
3248 else
3249 snprintf (buf, size, "#0x%" PRIx64, opnd->imm.value);
3250 break;
3251
3252 case AARCH64_OPND_SIMD_IMM:
3253 case AARCH64_OPND_SIMD_IMM_SFT:
3254 if ((! opnd->shifter.amount && opnd->shifter.kind == AARCH64_MOD_LSL)
3255 || opnd->shifter.kind == AARCH64_MOD_NONE)
3256 snprintf (buf, size, "#0x%" PRIx64, opnd->imm.value);
3257 else
2442d846 3258 snprintf (buf, size, "#0x%" PRIx64 ", %s #%" PRIi64, opnd->imm.value,
a06ea964
NC
3259 aarch64_operand_modifiers[opnd->shifter.kind].name,
3260 opnd->shifter.amount);
3261 break;
3262
e950b345
RS
3263 case AARCH64_OPND_SVE_AIMM:
3264 case AARCH64_OPND_SVE_ASIMM:
3265 if (opnd->shifter.amount)
3266 snprintf (buf, size, "#%" PRIi64 ", lsl #%" PRIi64, opnd->imm.value,
3267 opnd->shifter.amount);
3268 else
3269 snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
3270 break;
3271
a06ea964
NC
3272 case AARCH64_OPND_FPIMM:
3273 case AARCH64_OPND_SIMD_FPIMM:
165d4950 3274 case AARCH64_OPND_SVE_FPIMM8:
a06ea964
NC
3275 switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
3276 {
cf86120b
MW
3277 case 2: /* e.g. FMOV <Hd>, #<imm>. */
3278 {
3279 half_conv_t c;
3280 c.i = expand_fp_imm (2, opnd->imm.value);
3281 snprintf (buf, size, "#%.18e", c.f);
3282 }
3283 break;
a06ea964
NC
3284 case 4: /* e.g. FMOV <Vd>.4S, #<imm>. */
3285 {
3286 single_conv_t c;
cf86120b 3287 c.i = expand_fp_imm (4, opnd->imm.value);
a06ea964
NC
3288 snprintf (buf, size, "#%.18e", c.f);
3289 }
3290 break;
3291 case 8: /* e.g. FMOV <Sd>, #<imm>. */
3292 {
3293 double_conv_t c;
cf86120b 3294 c.i = expand_fp_imm (8, opnd->imm.value);
a06ea964
NC
3295 snprintf (buf, size, "#%.18e", c.d);
3296 }
3297 break;
3298 default: assert (0);
3299 }
3300 break;
3301
3302 case AARCH64_OPND_CCMP_IMM:
3303 case AARCH64_OPND_NZCV:
3304 case AARCH64_OPND_EXCEPTION:
3305 case AARCH64_OPND_UIMM4:
3306 case AARCH64_OPND_UIMM7:
3307 if (optional_operand_p (opcode, idx) == TRUE
3308 && (opnd->imm.value ==
3309 (int64_t) get_optional_operand_default_value (opcode)))
3310 /* Omit the operand, e.g. DCPS1. */
3311 break;
3312 snprintf (buf, size, "#0x%x", (unsigned int)opnd->imm.value);
3313 break;
3314
3315 case AARCH64_OPND_COND:
68a64283 3316 case AARCH64_OPND_COND1:
a06ea964 3317 snprintf (buf, size, "%s", opnd->cond->names[0]);
bb7eff52
RS
3318 num_conds = ARRAY_SIZE (opnd->cond->names);
3319 for (i = 1; i < num_conds && opnd->cond->names[i]; ++i)
3320 {
3321 size_t len = strlen (buf);
3322 if (i == 1)
3323 snprintf (buf + len, size - len, " // %s = %s",
3324 opnd->cond->names[0], opnd->cond->names[i]);
3325 else
3326 snprintf (buf + len, size - len, ", %s",
3327 opnd->cond->names[i]);
3328 }
a06ea964
NC
3329 break;
3330
3331 case AARCH64_OPND_ADDR_ADRP:
3332 addr = ((pc + AARCH64_PCREL_OFFSET) & ~(uint64_t)0xfff)
3333 + opnd->imm.value;
3334 if (pcrel_p)
3335 *pcrel_p = 1;
3336 if (address)
3337 *address = addr;
3338 /* This is not necessary during the disassembling, as print_address_func
3339 in the disassemble_info will take care of the printing. But some
3340 other callers may be still interested in getting the string in *STR,
3341 so here we do snprintf regardless. */
3342 snprintf (buf, size, "#0x%" PRIx64, addr);
3343 break;
3344
3345 case AARCH64_OPND_ADDR_PCREL14:
3346 case AARCH64_OPND_ADDR_PCREL19:
3347 case AARCH64_OPND_ADDR_PCREL21:
3348 case AARCH64_OPND_ADDR_PCREL26:
3349 addr = pc + AARCH64_PCREL_OFFSET + opnd->imm.value;
3350 if (pcrel_p)
3351 *pcrel_p = 1;
3352 if (address)
3353 *address = addr;
3354 /* This is not necessary during the disassembling, as print_address_func
3355 in the disassemble_info will take care of the printing. But some
3356 other callers may be still interested in getting the string in *STR,
3357 so here we do snprintf regardless. */
3358 snprintf (buf, size, "#0x%" PRIx64, addr);
3359 break;
3360
3361 case AARCH64_OPND_ADDR_SIMPLE:
3362 case AARCH64_OPND_SIMD_ADDR_SIMPLE:
3363 case AARCH64_OPND_SIMD_ADDR_POST:
3364 name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
3365 if (opnd->type == AARCH64_OPND_SIMD_ADDR_POST)
3366 {
3367 if (opnd->addr.offset.is_reg)
3368 snprintf (buf, size, "[%s], x%d", name, opnd->addr.offset.regno);
3369 else
3370 snprintf (buf, size, "[%s], #%d", name, opnd->addr.offset.imm);
3371 }
3372 else
3373 snprintf (buf, size, "[%s]", name);
3374 break;
3375
3376 case AARCH64_OPND_ADDR_REGOFF:
4df068de
RS
3377 case AARCH64_OPND_SVE_ADDR_RR:
3378 case AARCH64_OPND_SVE_ADDR_RR_LSL1:
3379 case AARCH64_OPND_SVE_ADDR_RR_LSL2:
3380 case AARCH64_OPND_SVE_ADDR_RR_LSL3:
3381 case AARCH64_OPND_SVE_ADDR_RX:
3382 case AARCH64_OPND_SVE_ADDR_RX_LSL1:
3383 case AARCH64_OPND_SVE_ADDR_RX_LSL2:
3384 case AARCH64_OPND_SVE_ADDR_RX_LSL3:
01dbfe4c
RS
3385 print_register_offset_address
3386 (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
3387 get_offset_int_reg_name (opnd));
a06ea964
NC
3388 break;
3389
4df068de
RS
3390 case AARCH64_OPND_SVE_ADDR_RZ:
3391 case AARCH64_OPND_SVE_ADDR_RZ_LSL1:
3392 case AARCH64_OPND_SVE_ADDR_RZ_LSL2:
3393 case AARCH64_OPND_SVE_ADDR_RZ_LSL3:
3394 case AARCH64_OPND_SVE_ADDR_RZ_XTW_14:
3395 case AARCH64_OPND_SVE_ADDR_RZ_XTW_22:
3396 case AARCH64_OPND_SVE_ADDR_RZ_XTW1_14:
3397 case AARCH64_OPND_SVE_ADDR_RZ_XTW1_22:
3398 case AARCH64_OPND_SVE_ADDR_RZ_XTW2_14:
3399 case AARCH64_OPND_SVE_ADDR_RZ_XTW2_22:
3400 case AARCH64_OPND_SVE_ADDR_RZ_XTW3_14:
3401 case AARCH64_OPND_SVE_ADDR_RZ_XTW3_22:
3402 print_register_offset_address
3403 (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
3404 get_addr_sve_reg_name (opnd->addr.offset.regno, opnd->qualifier));
3405 break;
3406
a06ea964
NC
3407 case AARCH64_OPND_ADDR_SIMM7:
3408 case AARCH64_OPND_ADDR_SIMM9:
3409 case AARCH64_OPND_ADDR_SIMM9_2:
98907a70
RS
3410 case AARCH64_OPND_SVE_ADDR_RI_S4xVL:
3411 case AARCH64_OPND_SVE_ADDR_RI_S4x2xVL:
3412 case AARCH64_OPND_SVE_ADDR_RI_S4x3xVL:
3413 case AARCH64_OPND_SVE_ADDR_RI_S4x4xVL:
3414 case AARCH64_OPND_SVE_ADDR_RI_S6xVL:
3415 case AARCH64_OPND_SVE_ADDR_RI_S9xVL:
4df068de
RS
3416 case AARCH64_OPND_SVE_ADDR_RI_U6:
3417 case AARCH64_OPND_SVE_ADDR_RI_U6x2:
3418 case AARCH64_OPND_SVE_ADDR_RI_U6x4:
3419 case AARCH64_OPND_SVE_ADDR_RI_U6x8:
01dbfe4c
RS
3420 print_immediate_offset_address
3421 (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1));
a06ea964
NC
3422 break;
3423
4df068de
RS
3424 case AARCH64_OPND_SVE_ADDR_ZI_U5:
3425 case AARCH64_OPND_SVE_ADDR_ZI_U5x2:
3426 case AARCH64_OPND_SVE_ADDR_ZI_U5x4:
3427 case AARCH64_OPND_SVE_ADDR_ZI_U5x8:
3428 print_immediate_offset_address
3429 (buf, size, opnd,
3430 get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier));
3431 break;
3432
3433 case AARCH64_OPND_SVE_ADDR_ZZ_LSL:
3434 case AARCH64_OPND_SVE_ADDR_ZZ_SXTW:
3435 case AARCH64_OPND_SVE_ADDR_ZZ_UXTW:
3436 print_register_offset_address
3437 (buf, size, opnd,
3438 get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier),
3439 get_addr_sve_reg_name (opnd->addr.offset.regno, opnd->qualifier));
3440 break;
3441
a06ea964
NC
3442 case AARCH64_OPND_ADDR_UIMM12:
3443 name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
3444 if (opnd->addr.offset.imm)
ad43e107 3445 snprintf (buf, size, "[%s, #%d]", name, opnd->addr.offset.imm);
a06ea964
NC
3446 else
3447 snprintf (buf, size, "[%s]", name);
3448 break;
3449
3450 case AARCH64_OPND_SYSREG:
3451 for (i = 0; aarch64_sys_regs[i].name; ++i)
49eec193
YZ
3452 if (aarch64_sys_regs[i].value == opnd->sysreg
3453 && ! aarch64_sys_reg_deprecated_p (&aarch64_sys_regs[i]))
a06ea964
NC
3454 break;
3455 if (aarch64_sys_regs[i].name)
3456 snprintf (buf, size, "%s", aarch64_sys_regs[i].name);
3457 else
3458 {
3459 /* Implementation defined system register. */
3460 unsigned int value = opnd->sysreg;
3461 snprintf (buf, size, "s%u_%u_c%u_c%u_%u", (value >> 14) & 0x3,
3462 (value >> 11) & 0x7, (value >> 7) & 0xf, (value >> 3) & 0xf,
3463 value & 0x7);
3464 }
3465 break;
3466
3467 case AARCH64_OPND_PSTATEFIELD:
3468 for (i = 0; aarch64_pstatefields[i].name; ++i)
3469 if (aarch64_pstatefields[i].value == opnd->pstatefield)
3470 break;
3471 assert (aarch64_pstatefields[i].name);
3472 snprintf (buf, size, "%s", aarch64_pstatefields[i].name);
3473 break;
3474
3475 case AARCH64_OPND_SYSREG_AT:
3476 case AARCH64_OPND_SYSREG_DC:
3477 case AARCH64_OPND_SYSREG_IC:
3478 case AARCH64_OPND_SYSREG_TLBI:
875880c6 3479 snprintf (buf, size, "%s", opnd->sysins_op->name);
a06ea964
NC
3480 break;
3481
3482 case AARCH64_OPND_BARRIER:
3483 snprintf (buf, size, "%s", opnd->barrier->name);
3484 break;
3485
3486 case AARCH64_OPND_BARRIER_ISB:
3487 /* Operand can be omitted, e.g. in DCPS1. */
3488 if (! optional_operand_p (opcode, idx)
3489 || (opnd->barrier->value
3490 != get_optional_operand_default_value (opcode)))
3491 snprintf (buf, size, "#0x%x", opnd->barrier->value);
3492 break;
3493
3494 case AARCH64_OPND_PRFOP:
a1ccaec9
YZ
3495 if (opnd->prfop->name != NULL)
3496 snprintf (buf, size, "%s", opnd->prfop->name);
3497 else
3498 snprintf (buf, size, "#0x%02x", opnd->prfop->value);
a06ea964
NC
3499 break;
3500
1e6f4800
MW
3501 case AARCH64_OPND_BARRIER_PSB:
3502 snprintf (buf, size, "%s", opnd->hint_option->name);
3503 break;
3504
a06ea964
NC
3505 default:
3506 assert (0);
3507 }
3508}
3509\f
3510#define CPENC(op0,op1,crn,crm,op2) \
3511 ((((op0) << 19) | ((op1) << 16) | ((crn) << 12) | ((crm) << 8) | ((op2) << 5)) >> 5)
3512 /* for 3.9.3 Instructions for Accessing Special Purpose Registers */
3513#define CPEN_(op1,crm,op2) CPENC(3,(op1),4,(crm),(op2))
3514 /* for 3.9.10 System Instructions */
3515#define CPENS(op1,crn,crm,op2) CPENC(1,(op1),(crn),(crm),(op2))
3516
3517#define C0 0
3518#define C1 1
3519#define C2 2
3520#define C3 3
3521#define C4 4
3522#define C5 5
3523#define C6 6
3524#define C7 7
3525#define C8 8
3526#define C9 9
3527#define C10 10
3528#define C11 11
3529#define C12 12
3530#define C13 13
3531#define C14 14
3532#define C15 15
3533
49eec193
YZ
3534#ifdef F_DEPRECATED
3535#undef F_DEPRECATED
3536#endif
3537#define F_DEPRECATED 0x1 /* Deprecated system register. */
3538
f21cce2c
MW
3539#ifdef F_ARCHEXT
3540#undef F_ARCHEXT
3541#endif
3542#define F_ARCHEXT 0x2 /* Architecture dependent system register. */
3543
ea2deeec
MW
3544#ifdef F_HASXT
3545#undef F_HASXT
3546#endif
3547#define F_HASXT 0x4 /* System instruction register <Xt>
3548 operand. */
3549
f21cce2c 3550
a06ea964
NC
3551/* TODO there are two more issues need to be resolved
3552 1. handle read-only and write-only system registers
3553 2. handle cpu-implementation-defined system registers. */
49eec193
YZ
3554const aarch64_sys_reg aarch64_sys_regs [] =
3555{
3556 { "spsr_el1", CPEN_(0,C0,0), 0 }, /* = spsr_svc */
250aafa4 3557 { "spsr_el12", CPEN_ (5, C0, 0), F_ARCHEXT },
49eec193 3558 { "elr_el1", CPEN_(0,C0,1), 0 },
250aafa4 3559 { "elr_el12", CPEN_ (5, C0, 1), F_ARCHEXT },
49eec193
YZ
3560 { "sp_el0", CPEN_(0,C1,0), 0 },
3561 { "spsel", CPEN_(0,C2,0), 0 },
3562 { "daif", CPEN_(3,C2,1), 0 },
3563 { "currentel", CPEN_(0,C2,2), 0 }, /* RO */
f21cce2c 3564 { "pan", CPEN_(0,C2,3), F_ARCHEXT },
6479e48e 3565 { "uao", CPEN_ (0, C2, 4), F_ARCHEXT },
49eec193
YZ
3566 { "nzcv", CPEN_(3,C2,0), 0 },
3567 { "fpcr", CPEN_(3,C4,0), 0 },
3568 { "fpsr", CPEN_(3,C4,1), 0 },
3569 { "dspsr_el0", CPEN_(3,C5,0), 0 },
3570 { "dlr_el0", CPEN_(3,C5,1), 0 },
3571 { "spsr_el2", CPEN_(4,C0,0), 0 }, /* = spsr_hyp */
3572 { "elr_el2", CPEN_(4,C0,1), 0 },
3573 { "sp_el1", CPEN_(4,C1,0), 0 },
3574 { "spsr_irq", CPEN_(4,C3,0), 0 },
3575 { "spsr_abt", CPEN_(4,C3,1), 0 },
3576 { "spsr_und", CPEN_(4,C3,2), 0 },
3577 { "spsr_fiq", CPEN_(4,C3,3), 0 },
3578 { "spsr_el3", CPEN_(6,C0,0), 0 },
3579 { "elr_el3", CPEN_(6,C0,1), 0 },
3580 { "sp_el2", CPEN_(6,C1,0), 0 },
3581 { "spsr_svc", CPEN_(0,C0,0), F_DEPRECATED }, /* = spsr_el1 */
3582 { "spsr_hyp", CPEN_(4,C0,0), F_DEPRECATED }, /* = spsr_el2 */
3583 { "midr_el1", CPENC(3,0,C0,C0,0), 0 }, /* RO */
3584 { "ctr_el0", CPENC(3,3,C0,C0,1), 0 }, /* RO */
3585 { "mpidr_el1", CPENC(3,0,C0,C0,5), 0 }, /* RO */
3586 { "revidr_el1", CPENC(3,0,C0,C0,6), 0 }, /* RO */
3587 { "aidr_el1", CPENC(3,1,C0,C0,7), 0 }, /* RO */
3588 { "dczid_el0", CPENC(3,3,C0,C0,7), 0 }, /* RO */
3589 { "id_dfr0_el1", CPENC(3,0,C0,C1,2), 0 }, /* RO */
3590 { "id_pfr0_el1", CPENC(3,0,C0,C1,0), 0 }, /* RO */
3591 { "id_pfr1_el1", CPENC(3,0,C0,C1,1), 0 }, /* RO */
3592 { "id_afr0_el1", CPENC(3,0,C0,C1,3), 0 }, /* RO */
3593 { "id_mmfr0_el1", CPENC(3,0,C0,C1,4), 0 }, /* RO */
3594 { "id_mmfr1_el1", CPENC(3,0,C0,C1,5), 0 }, /* RO */
3595 { "id_mmfr2_el1", CPENC(3,0,C0,C1,6), 0 }, /* RO */
3596 { "id_mmfr3_el1", CPENC(3,0,C0,C1,7), 0 }, /* RO */
bdfa8b95 3597 { "id_mmfr4_el1", CPENC(3,0,C0,C2,6), 0 }, /* RO */
49eec193
YZ
3598 { "id_isar0_el1", CPENC(3,0,C0,C2,0), 0 }, /* RO */
3599 { "id_isar1_el1", CPENC(3,0,C0,C2,1), 0 }, /* RO */
3600 { "id_isar2_el1", CPENC(3,0,C0,C2,2), 0 }, /* RO */
3601 { "id_isar3_el1", CPENC(3,0,C0,C2,3), 0 }, /* RO */
3602 { "id_isar4_el1", CPENC(3,0,C0,C2,4), 0 }, /* RO */
3603 { "id_isar5_el1", CPENC(3,0,C0,C2,5), 0 }, /* RO */
3604 { "mvfr0_el1", CPENC(3,0,C0,C3,0), 0 }, /* RO */
3605 { "mvfr1_el1", CPENC(3,0,C0,C3,1), 0 }, /* RO */
3606 { "mvfr2_el1", CPENC(3,0,C0,C3,2), 0 }, /* RO */
3607 { "ccsidr_el1", CPENC(3,1,C0,C0,0), 0 }, /* RO */
3608 { "id_aa64pfr0_el1", CPENC(3,0,C0,C4,0), 0 }, /* RO */
3609 { "id_aa64pfr1_el1", CPENC(3,0,C0,C4,1), 0 }, /* RO */
3610 { "id_aa64dfr0_el1", CPENC(3,0,C0,C5,0), 0 }, /* RO */
3611 { "id_aa64dfr1_el1", CPENC(3,0,C0,C5,1), 0 }, /* RO */
3612 { "id_aa64isar0_el1", CPENC(3,0,C0,C6,0), 0 }, /* RO */
3613 { "id_aa64isar1_el1", CPENC(3,0,C0,C6,1), 0 }, /* RO */
3614 { "id_aa64mmfr0_el1", CPENC(3,0,C0,C7,0), 0 }, /* RO */
3615 { "id_aa64mmfr1_el1", CPENC(3,0,C0,C7,1), 0 }, /* RO */
1a04d1a7 3616 { "id_aa64mmfr2_el1", CPENC (3, 0, C0, C7, 2), F_ARCHEXT }, /* RO */
49eec193
YZ
3617 { "id_aa64afr0_el1", CPENC(3,0,C0,C5,4), 0 }, /* RO */
3618 { "id_aa64afr1_el1", CPENC(3,0,C0,C5,5), 0 }, /* RO */
3619 { "clidr_el1", CPENC(3,1,C0,C0,1), 0 }, /* RO */
3620 { "csselr_el1", CPENC(3,2,C0,C0,0), 0 }, /* RO */
3621 { "vpidr_el2", CPENC(3,4,C0,C0,0), 0 },
3622 { "vmpidr_el2", CPENC(3,4,C0,C0,5), 0 },
3623 { "sctlr_el1", CPENC(3,0,C1,C0,0), 0 },
3624 { "sctlr_el2", CPENC(3,4,C1,C0,0), 0 },
3625 { "sctlr_el3", CPENC(3,6,C1,C0,0), 0 },
250aafa4 3626 { "sctlr_el12", CPENC (3, 5, C1, C0, 0), F_ARCHEXT },
49eec193
YZ
3627 { "actlr_el1", CPENC(3,0,C1,C0,1), 0 },
3628 { "actlr_el2", CPENC(3,4,C1,C0,1), 0 },
3629 { "actlr_el3", CPENC(3,6,C1,C0,1), 0 },
3630 { "cpacr_el1", CPENC(3,0,C1,C0,2), 0 },
250aafa4 3631 { "cpacr_el12", CPENC (3, 5, C1, C0, 2), F_ARCHEXT },
49eec193
YZ
3632 { "cptr_el2", CPENC(3,4,C1,C1,2), 0 },
3633 { "cptr_el3", CPENC(3,6,C1,C1,2), 0 },
3634 { "scr_el3", CPENC(3,6,C1,C1,0), 0 },
3635 { "hcr_el2", CPENC(3,4,C1,C1,0), 0 },
3636 { "mdcr_el2", CPENC(3,4,C1,C1,1), 0 },
3637 { "mdcr_el3", CPENC(3,6,C1,C3,1), 0 },
3638 { "hstr_el2", CPENC(3,4,C1,C1,3), 0 },
3639 { "hacr_el2", CPENC(3,4,C1,C1,7), 0 },
3640 { "ttbr0_el1", CPENC(3,0,C2,C0,0), 0 },
3641 { "ttbr1_el1", CPENC(3,0,C2,C0,1), 0 },
3642 { "ttbr0_el2", CPENC(3,4,C2,C0,0), 0 },
250aafa4 3643 { "ttbr1_el2", CPENC (3, 4, C2, C0, 1), F_ARCHEXT },
49eec193 3644 { "ttbr0_el3", CPENC(3,6,C2,C0,0), 0 },
250aafa4
MW
3645 { "ttbr0_el12", CPENC (3, 5, C2, C0, 0), F_ARCHEXT },
3646 { "ttbr1_el12", CPENC (3, 5, C2, C0, 1), F_ARCHEXT },
49eec193
YZ
3647 { "vttbr_el2", CPENC(3,4,C2,C1,0), 0 },
3648 { "tcr_el1", CPENC(3,0,C2,C0,2), 0 },
3649 { "tcr_el2", CPENC(3,4,C2,C0,2), 0 },
3650 { "tcr_el3", CPENC(3,6,C2,C0,2), 0 },
250aafa4 3651 { "tcr_el12", CPENC (3, 5, C2, C0, 2), F_ARCHEXT },
49eec193
YZ
3652 { "vtcr_el2", CPENC(3,4,C2,C1,2), 0 },
3653 { "afsr0_el1", CPENC(3,0,C5,C1,0), 0 },
3654 { "afsr1_el1", CPENC(3,0,C5,C1,1), 0 },
3655 { "afsr0_el2", CPENC(3,4,C5,C1,0), 0 },
3656 { "afsr1_el2", CPENC(3,4,C5,C1,1), 0 },
3657 { "afsr0_el3", CPENC(3,6,C5,C1,0), 0 },
250aafa4 3658 { "afsr0_el12", CPENC (3, 5, C5, C1, 0), F_ARCHEXT },
49eec193 3659 { "afsr1_el3", CPENC(3,6,C5,C1,1), 0 },
250aafa4 3660 { "afsr1_el12", CPENC (3, 5, C5, C1, 1), F_ARCHEXT },
49eec193
YZ
3661 { "esr_el1", CPENC(3,0,C5,C2,0), 0 },
3662 { "esr_el2", CPENC(3,4,C5,C2,0), 0 },
3663 { "esr_el3", CPENC(3,6,C5,C2,0), 0 },
250aafa4 3664 { "esr_el12", CPENC (3, 5, C5, C2, 0), F_ARCHEXT },
47f81142 3665 { "vsesr_el2", CPENC (3, 4, C5, C2, 3), F_ARCHEXT }, /* RO */
49eec193 3666 { "fpexc32_el2", CPENC(3,4,C5,C3,0), 0 },
47f81142
MW
3667 { "erridr_el1", CPENC (3, 0, C5, C3, 0), F_ARCHEXT }, /* RO */
3668 { "errselr_el1", CPENC (3, 0, C5, C3, 1), F_ARCHEXT },
3669 { "erxfr_el1", CPENC (3, 0, C5, C4, 0), F_ARCHEXT }, /* RO */
3670 { "erxctlr_el1", CPENC (3, 0, C5, C4, 1), F_ARCHEXT },
3671 { "erxstatus_el1", CPENC (3, 0, C5, C4, 2), F_ARCHEXT },
3672 { "erxaddr_el1", CPENC (3, 0, C5, C4, 3), F_ARCHEXT },
3673 { "erxmisc0_el1", CPENC (3, 0, C5, C5, 0), F_ARCHEXT },
3674 { "erxmisc1_el1", CPENC (3, 0, C5, C5, 1), F_ARCHEXT },
49eec193
YZ
3675 { "far_el1", CPENC(3,0,C6,C0,0), 0 },
3676 { "far_el2", CPENC(3,4,C6,C0,0), 0 },
3677 { "far_el3", CPENC(3,6,C6,C0,0), 0 },
250aafa4 3678 { "far_el12", CPENC (3, 5, C6, C0, 0), F_ARCHEXT },
49eec193
YZ
3679 { "hpfar_el2", CPENC(3,4,C6,C0,4), 0 },
3680 { "par_el1", CPENC(3,0,C7,C4,0), 0 },
3681 { "mair_el1", CPENC(3,0,C10,C2,0), 0 },
3682 { "mair_el2", CPENC(3,4,C10,C2,0), 0 },
3683 { "mair_el3", CPENC(3,6,C10,C2,0), 0 },
250aafa4 3684 { "mair_el12", CPENC (3, 5, C10, C2, 0), F_ARCHEXT },
49eec193
YZ
3685 { "amair_el1", CPENC(3,0,C10,C3,0), 0 },
3686 { "amair_el2", CPENC(3,4,C10,C3,0), 0 },
3687 { "amair_el3", CPENC(3,6,C10,C3,0), 0 },
250aafa4 3688 { "amair_el12", CPENC (3, 5, C10, C3, 0), F_ARCHEXT },
49eec193
YZ
3689 { "vbar_el1", CPENC(3,0,C12,C0,0), 0 },
3690 { "vbar_el2", CPENC(3,4,C12,C0,0), 0 },
3691 { "vbar_el3", CPENC(3,6,C12,C0,0), 0 },
250aafa4 3692 { "vbar_el12", CPENC (3, 5, C12, C0, 0), F_ARCHEXT },
49eec193
YZ
3693 { "rvbar_el1", CPENC(3,0,C12,C0,1), 0 }, /* RO */
3694 { "rvbar_el2", CPENC(3,4,C12,C0,1), 0 }, /* RO */
3695 { "rvbar_el3", CPENC(3,6,C12,C0,1), 0 }, /* RO */
3696 { "rmr_el1", CPENC(3,0,C12,C0,2), 0 },
3697 { "rmr_el2", CPENC(3,4,C12,C0,2), 0 },
3698 { "rmr_el3", CPENC(3,6,C12,C0,2), 0 },
3699 { "isr_el1", CPENC(3,0,C12,C1,0), 0 }, /* RO */
47f81142
MW
3700 { "disr_el1", CPENC (3, 0, C12, C1, 1), F_ARCHEXT },
3701 { "vdisr_el2", CPENC (3, 4, C12, C1, 1), F_ARCHEXT },
49eec193 3702 { "contextidr_el1", CPENC(3,0,C13,C0,1), 0 },
250aafa4
MW
3703 { "contextidr_el2", CPENC (3, 4, C13, C0, 1), F_ARCHEXT },
3704 { "contextidr_el12", CPENC (3, 5, C13, C0, 1), F_ARCHEXT },
49eec193
YZ
3705 { "tpidr_el0", CPENC(3,3,C13,C0,2), 0 },
3706 { "tpidrro_el0", CPENC(3,3,C13,C0,3), 0 }, /* RO */
3707 { "tpidr_el1", CPENC(3,0,C13,C0,4), 0 },
3708 { "tpidr_el2", CPENC(3,4,C13,C0,2), 0 },
3709 { "tpidr_el3", CPENC(3,6,C13,C0,2), 0 },
3710 { "teecr32_el1", CPENC(2,2,C0, C0,0), 0 }, /* See section 3.9.7.1 */
3711 { "cntfrq_el0", CPENC(3,3,C14,C0,0), 0 }, /* RO */
3712 { "cntpct_el0", CPENC(3,3,C14,C0,1), 0 }, /* RO */
3713 { "cntvct_el0", CPENC(3,3,C14,C0,2), 0 }, /* RO */
3714 { "cntvoff_el2", CPENC(3,4,C14,C0,3), 0 },
3715 { "cntkctl_el1", CPENC(3,0,C14,C1,0), 0 },
250aafa4 3716 { "cntkctl_el12", CPENC (3, 5, C14, C1, 0), F_ARCHEXT },
49eec193
YZ
3717 { "cnthctl_el2", CPENC(3,4,C14,C1,0), 0 },
3718 { "cntp_tval_el0", CPENC(3,3,C14,C2,0), 0 },
250aafa4 3719 { "cntp_tval_el02", CPENC (3, 5, C14, C2, 0), F_ARCHEXT },
49eec193 3720 { "cntp_ctl_el0", CPENC(3,3,C14,C2,1), 0 },
250aafa4 3721 { "cntp_ctl_el02", CPENC (3, 5, C14, C2, 1), F_ARCHEXT },
49eec193 3722 { "cntp_cval_el0", CPENC(3,3,C14,C2,2), 0 },
250aafa4 3723 { "cntp_cval_el02", CPENC (3, 5, C14, C2, 2), F_ARCHEXT },
49eec193 3724 { "cntv_tval_el0", CPENC(3,3,C14,C3,0), 0 },
250aafa4 3725 { "cntv_tval_el02", CPENC (3, 5, C14, C3, 0), F_ARCHEXT },
49eec193 3726 { "cntv_ctl_el0", CPENC(3,3,C14,C3,1), 0 },
250aafa4 3727 { "cntv_ctl_el02", CPENC (3, 5, C14, C3, 1), F_ARCHEXT },
49eec193 3728 { "cntv_cval_el0", CPENC(3,3,C14,C3,2), 0 },
250aafa4 3729 { "cntv_cval_el02", CPENC (3, 5, C14, C3, 2), F_ARCHEXT },
49eec193
YZ
3730 { "cnthp_tval_el2", CPENC(3,4,C14,C2,0), 0 },
3731 { "cnthp_ctl_el2", CPENC(3,4,C14,C2,1), 0 },
3732 { "cnthp_cval_el2", CPENC(3,4,C14,C2,2), 0 },
3733 { "cntps_tval_el1", CPENC(3,7,C14,C2,0), 0 },
3734 { "cntps_ctl_el1", CPENC(3,7,C14,C2,1), 0 },
3735 { "cntps_cval_el1", CPENC(3,7,C14,C2,2), 0 },
250aafa4
MW
3736 { "cnthv_tval_el2", CPENC (3, 4, C14, C3, 0), F_ARCHEXT },
3737 { "cnthv_ctl_el2", CPENC (3, 4, C14, C3, 1), F_ARCHEXT },
3738 { "cnthv_cval_el2", CPENC (3, 4, C14, C3, 2), F_ARCHEXT },
49eec193
YZ
3739 { "dacr32_el2", CPENC(3,4,C3,C0,0), 0 },
3740 { "ifsr32_el2", CPENC(3,4,C5,C0,1), 0 },
3741 { "teehbr32_el1", CPENC(2,2,C1,C0,0), 0 },
3742 { "sder32_el3", CPENC(3,6,C1,C1,1), 0 },
3743 { "mdscr_el1", CPENC(2,0,C0, C2, 2), 0 },
3744 { "mdccsr_el0", CPENC(2,3,C0, C1, 0), 0 }, /* r */
3745 { "mdccint_el1", CPENC(2,0,C0, C2, 0), 0 },
3746 { "dbgdtr_el0", CPENC(2,3,C0, C4, 0), 0 },
3747 { "dbgdtrrx_el0", CPENC(2,3,C0, C5, 0), 0 }, /* r */
3748 { "dbgdtrtx_el0", CPENC(2,3,C0, C5, 0), 0 }, /* w */
3749 { "osdtrrx_el1", CPENC(2,0,C0, C0, 2), 0 }, /* r */
3750 { "osdtrtx_el1", CPENC(2,0,C0, C3, 2), 0 }, /* w */
3751 { "oseccr_el1", CPENC(2,0,C0, C6, 2), 0 },
3752 { "dbgvcr32_el2", CPENC(2,4,C0, C7, 0), 0 },
3753 { "dbgbvr0_el1", CPENC(2,0,C0, C0, 4), 0 },
3754 { "dbgbvr1_el1", CPENC(2,0,C0, C1, 4), 0 },
3755 { "dbgbvr2_el1", CPENC(2,0,C0, C2, 4), 0 },
3756 { "dbgbvr3_el1", CPENC(2,0,C0, C3, 4), 0 },
3757 { "dbgbvr4_el1", CPENC(2,0,C0, C4, 4), 0 },
3758 { "dbgbvr5_el1", CPENC(2,0,C0, C5, 4), 0 },
3759 { "dbgbvr6_el1", CPENC(2,0,C0, C6, 4), 0 },
3760 { "dbgbvr7_el1", CPENC(2,0,C0, C7, 4), 0 },
3761 { "dbgbvr8_el1", CPENC(2,0,C0, C8, 4), 0 },
3762 { "dbgbvr9_el1", CPENC(2,0,C0, C9, 4), 0 },
3763 { "dbgbvr10_el1", CPENC(2,0,C0, C10,4), 0 },
3764 { "dbgbvr11_el1", CPENC(2,0,C0, C11,4), 0 },
3765 { "dbgbvr12_el1", CPENC(2,0,C0, C12,4), 0 },
3766 { "dbgbvr13_el1", CPENC(2,0,C0, C13,4), 0 },
3767 { "dbgbvr14_el1", CPENC(2,0,C0, C14,4), 0 },
3768 { "dbgbvr15_el1", CPENC(2,0,C0, C15,4), 0 },
3769 { "dbgbcr0_el1", CPENC(2,0,C0, C0, 5), 0 },
3770 { "dbgbcr1_el1", CPENC(2,0,C0, C1, 5), 0 },
3771 { "dbgbcr2_el1", CPENC(2,0,C0, C2, 5), 0 },
3772 { "dbgbcr3_el1", CPENC(2,0,C0, C3, 5), 0 },
3773 { "dbgbcr4_el1", CPENC(2,0,C0, C4, 5), 0 },
3774 { "dbgbcr5_el1", CPENC(2,0,C0, C5, 5), 0 },
3775 { "dbgbcr6_el1", CPENC(2,0,C0, C6, 5), 0 },
3776 { "dbgbcr7_el1", CPENC(2,0,C0, C7, 5), 0 },
3777 { "dbgbcr8_el1", CPENC(2,0,C0, C8, 5), 0 },
3778 { "dbgbcr9_el1", CPENC(2,0,C0, C9, 5), 0 },
3779 { "dbgbcr10_el1", CPENC(2,0,C0, C10,5), 0 },
3780 { "dbgbcr11_el1", CPENC(2,0,C0, C11,5), 0 },
3781 { "dbgbcr12_el1", CPENC(2,0,C0, C12,5), 0 },
3782 { "dbgbcr13_el1", CPENC(2,0,C0, C13,5), 0 },
3783 { "dbgbcr14_el1", CPENC(2,0,C0, C14,5), 0 },
3784 { "dbgbcr15_el1", CPENC(2,0,C0, C15,5), 0 },
3785 { "dbgwvr0_el1", CPENC(2,0,C0, C0, 6), 0 },
3786 { "dbgwvr1_el1", CPENC(2,0,C0, C1, 6), 0 },
3787 { "dbgwvr2_el1", CPENC(2,0,C0, C2, 6), 0 },
3788 { "dbgwvr3_el1", CPENC(2,0,C0, C3, 6), 0 },
3789 { "dbgwvr4_el1", CPENC(2,0,C0, C4, 6), 0 },
3790 { "dbgwvr5_el1", CPENC(2,0,C0, C5, 6), 0 },
3791 { "dbgwvr6_el1", CPENC(2,0,C0, C6, 6), 0 },
3792 { "dbgwvr7_el1", CPENC(2,0,C0, C7, 6), 0 },
3793 { "dbgwvr8_el1", CPENC(2,0,C0, C8, 6), 0 },
3794 { "dbgwvr9_el1", CPENC(2,0,C0, C9, 6), 0 },
3795 { "dbgwvr10_el1", CPENC(2,0,C0, C10,6), 0 },
3796 { "dbgwvr11_el1", CPENC(2,0,C0, C11,6), 0 },
3797 { "dbgwvr12_el1", CPENC(2,0,C0, C12,6), 0 },
3798 { "dbgwvr13_el1", CPENC(2,0,C0, C13,6), 0 },
3799 { "dbgwvr14_el1", CPENC(2,0,C0, C14,6), 0 },
3800 { "dbgwvr15_el1", CPENC(2,0,C0, C15,6), 0 },
3801 { "dbgwcr0_el1", CPENC(2,0,C0, C0, 7), 0 },
3802 { "dbgwcr1_el1", CPENC(2,0,C0, C1, 7), 0 },
3803 { "dbgwcr2_el1", CPENC(2,0,C0, C2, 7), 0 },
3804 { "dbgwcr3_el1", CPENC(2,0,C0, C3, 7), 0 },
3805 { "dbgwcr4_el1", CPENC(2,0,C0, C4, 7), 0 },
3806 { "dbgwcr5_el1", CPENC(2,0,C0, C5, 7), 0 },
3807 { "dbgwcr6_el1", CPENC(2,0,C0, C6, 7), 0 },
3808 { "dbgwcr7_el1", CPENC(2,0,C0, C7, 7), 0 },
3809 { "dbgwcr8_el1", CPENC(2,0,C0, C8, 7), 0 },
3810 { "dbgwcr9_el1", CPENC(2,0,C0, C9, 7), 0 },
3811 { "dbgwcr10_el1", CPENC(2,0,C0, C10,7), 0 },
3812 { "dbgwcr11_el1", CPENC(2,0,C0, C11,7), 0 },
3813 { "dbgwcr12_el1", CPENC(2,0,C0, C12,7), 0 },
3814 { "dbgwcr13_el1", CPENC(2,0,C0, C13,7), 0 },
3815 { "dbgwcr14_el1", CPENC(2,0,C0, C14,7), 0 },
3816 { "dbgwcr15_el1", CPENC(2,0,C0, C15,7), 0 },
3817 { "mdrar_el1", CPENC(2,0,C1, C0, 0), 0 }, /* r */
3818 { "oslar_el1", CPENC(2,0,C1, C0, 4), 0 }, /* w */
3819 { "oslsr_el1", CPENC(2,0,C1, C1, 4), 0 }, /* r */
3820 { "osdlr_el1", CPENC(2,0,C1, C3, 4), 0 },
3821 { "dbgprcr_el1", CPENC(2,0,C1, C4, 4), 0 },
3822 { "dbgclaimset_el1", CPENC(2,0,C7, C8, 6), 0 },
3823 { "dbgclaimclr_el1", CPENC(2,0,C7, C9, 6), 0 },
3824 { "dbgauthstatus_el1", CPENC(2,0,C7, C14,6), 0 }, /* r */
55c144e6
MW
3825 { "pmblimitr_el1", CPENC (3, 0, C9, C10, 0), F_ARCHEXT }, /* rw */
3826 { "pmbptr_el1", CPENC (3, 0, C9, C10, 1), F_ARCHEXT }, /* rw */
3827 { "pmbsr_el1", CPENC (3, 0, C9, C10, 3), F_ARCHEXT }, /* rw */
3828 { "pmbidr_el1", CPENC (3, 0, C9, C10, 7), F_ARCHEXT }, /* ro */
3829 { "pmscr_el1", CPENC (3, 0, C9, C9, 0), F_ARCHEXT }, /* rw */
3830 { "pmsicr_el1", CPENC (3, 0, C9, C9, 2), F_ARCHEXT }, /* rw */
3831 { "pmsirr_el1", CPENC (3, 0, C9, C9, 3), F_ARCHEXT }, /* rw */
3832 { "pmsfcr_el1", CPENC (3, 0, C9, C9, 4), F_ARCHEXT }, /* rw */
3833 { "pmsevfr_el1", CPENC (3, 0, C9, C9, 5), F_ARCHEXT }, /* rw */
3834 { "pmslatfr_el1", CPENC (3, 0, C9, C9, 6), F_ARCHEXT }, /* rw */
3835 { "pmsidr_el1", CPENC (3, 0, C9, C9, 7), F_ARCHEXT }, /* ro */
3836 { "pmscr_el2", CPENC (3, 4, C9, C9, 0), F_ARCHEXT }, /* rw */
3837 { "pmscr_el12", CPENC (3, 5, C9, C9, 0), F_ARCHEXT }, /* rw */
49eec193
YZ
3838 { "pmcr_el0", CPENC(3,3,C9,C12, 0), 0 },
3839 { "pmcntenset_el0", CPENC(3,3,C9,C12, 1), 0 },
3840 { "pmcntenclr_el0", CPENC(3,3,C9,C12, 2), 0 },
3841 { "pmovsclr_el0", CPENC(3,3,C9,C12, 3), 0 },
3842 { "pmswinc_el0", CPENC(3,3,C9,C12, 4), 0 }, /* w */
3843 { "pmselr_el0", CPENC(3,3,C9,C12, 5), 0 },
3844 { "pmceid0_el0", CPENC(3,3,C9,C12, 6), 0 }, /* r */
3845 { "pmceid1_el0", CPENC(3,3,C9,C12, 7), 0 }, /* r */
3846 { "pmccntr_el0", CPENC(3,3,C9,C13, 0), 0 },
3847 { "pmxevtyper_el0", CPENC(3,3,C9,C13, 1), 0 },
3848 { "pmxevcntr_el0", CPENC(3,3,C9,C13, 2), 0 },
3849 { "pmuserenr_el0", CPENC(3,3,C9,C14, 0), 0 },
3850 { "pmintenset_el1", CPENC(3,0,C9,C14, 1), 0 },
3851 { "pmintenclr_el1", CPENC(3,0,C9,C14, 2), 0 },
3852 { "pmovsset_el0", CPENC(3,3,C9,C14, 3), 0 },
3853 { "pmevcntr0_el0", CPENC(3,3,C14,C8, 0), 0 },
3854 { "pmevcntr1_el0", CPENC(3,3,C14,C8, 1), 0 },
3855 { "pmevcntr2_el0", CPENC(3,3,C14,C8, 2), 0 },
3856 { "pmevcntr3_el0", CPENC(3,3,C14,C8, 3), 0 },
3857 { "pmevcntr4_el0", CPENC(3,3,C14,C8, 4), 0 },
3858 { "pmevcntr5_el0", CPENC(3,3,C14,C8, 5), 0 },
3859 { "pmevcntr6_el0", CPENC(3,3,C14,C8, 6), 0 },
3860 { "pmevcntr7_el0", CPENC(3,3,C14,C8, 7), 0 },
3861 { "pmevcntr8_el0", CPENC(3,3,C14,C9, 0), 0 },
3862 { "pmevcntr9_el0", CPENC(3,3,C14,C9, 1), 0 },
3863 { "pmevcntr10_el0", CPENC(3,3,C14,C9, 2), 0 },
3864 { "pmevcntr11_el0", CPENC(3,3,C14,C9, 3), 0 },
3865 { "pmevcntr12_el0", CPENC(3,3,C14,C9, 4), 0 },
3866 { "pmevcntr13_el0", CPENC(3,3,C14,C9, 5), 0 },
3867 { "pmevcntr14_el0", CPENC(3,3,C14,C9, 6), 0 },
3868 { "pmevcntr15_el0", CPENC(3,3,C14,C9, 7), 0 },
3869 { "pmevcntr16_el0", CPENC(3,3,C14,C10,0), 0 },
3870 { "pmevcntr17_el0", CPENC(3,3,C14,C10,1), 0 },
3871 { "pmevcntr18_el0", CPENC(3,3,C14,C10,2), 0 },
3872 { "pmevcntr19_el0", CPENC(3,3,C14,C10,3), 0 },
3873 { "pmevcntr20_el0", CPENC(3,3,C14,C10,4), 0 },
3874 { "pmevcntr21_el0", CPENC(3,3,C14,C10,5), 0 },
3875 { "pmevcntr22_el0", CPENC(3,3,C14,C10,6), 0 },
3876 { "pmevcntr23_el0", CPENC(3,3,C14,C10,7), 0 },
3877 { "pmevcntr24_el0", CPENC(3,3,C14,C11,0), 0 },
3878 { "pmevcntr25_el0", CPENC(3,3,C14,C11,1), 0 },
3879 { "pmevcntr26_el0", CPENC(3,3,C14,C11,2), 0 },
3880 { "pmevcntr27_el0", CPENC(3,3,C14,C11,3), 0 },
3881 { "pmevcntr28_el0", CPENC(3,3,C14,C11,4), 0 },
3882 { "pmevcntr29_el0", CPENC(3,3,C14,C11,5), 0 },
3883 { "pmevcntr30_el0", CPENC(3,3,C14,C11,6), 0 },
3884 { "pmevtyper0_el0", CPENC(3,3,C14,C12,0), 0 },
3885 { "pmevtyper1_el0", CPENC(3,3,C14,C12,1), 0 },
3886 { "pmevtyper2_el0", CPENC(3,3,C14,C12,2), 0 },
3887 { "pmevtyper3_el0", CPENC(3,3,C14,C12,3), 0 },
3888 { "pmevtyper4_el0", CPENC(3,3,C14,C12,4), 0 },
3889 { "pmevtyper5_el0", CPENC(3,3,C14,C12,5), 0 },
3890 { "pmevtyper6_el0", CPENC(3,3,C14,C12,6), 0 },
3891 { "pmevtyper7_el0", CPENC(3,3,C14,C12,7), 0 },
3892 { "pmevtyper8_el0", CPENC(3,3,C14,C13,0), 0 },
3893 { "pmevtyper9_el0", CPENC(3,3,C14,C13,1), 0 },
3894 { "pmevtyper10_el0", CPENC(3,3,C14,C13,2), 0 },
3895 { "pmevtyper11_el0", CPENC(3,3,C14,C13,3), 0 },
3896 { "pmevtyper12_el0", CPENC(3,3,C14,C13,4), 0 },
3897 { "pmevtyper13_el0", CPENC(3,3,C14,C13,5), 0 },
3898 { "pmevtyper14_el0", CPENC(3,3,C14,C13,6), 0 },
3899 { "pmevtyper15_el0", CPENC(3,3,C14,C13,7), 0 },
3900 { "pmevtyper16_el0", CPENC(3,3,C14,C14,0), 0 },
3901 { "pmevtyper17_el0", CPENC(3,3,C14,C14,1), 0 },
3902 { "pmevtyper18_el0", CPENC(3,3,C14,C14,2), 0 },
3903 { "pmevtyper19_el0", CPENC(3,3,C14,C14,3), 0 },
3904 { "pmevtyper20_el0", CPENC(3,3,C14,C14,4), 0 },
3905 { "pmevtyper21_el0", CPENC(3,3,C14,C14,5), 0 },
3906 { "pmevtyper22_el0", CPENC(3,3,C14,C14,6), 0 },
3907 { "pmevtyper23_el0", CPENC(3,3,C14,C14,7), 0 },
3908 { "pmevtyper24_el0", CPENC(3,3,C14,C15,0), 0 },
3909 { "pmevtyper25_el0", CPENC(3,3,C14,C15,1), 0 },
3910 { "pmevtyper26_el0", CPENC(3,3,C14,C15,2), 0 },
3911 { "pmevtyper27_el0", CPENC(3,3,C14,C15,3), 0 },
3912 { "pmevtyper28_el0", CPENC(3,3,C14,C15,4), 0 },
3913 { "pmevtyper29_el0", CPENC(3,3,C14,C15,5), 0 },
3914 { "pmevtyper30_el0", CPENC(3,3,C14,C15,6), 0 },
3915 { "pmccfiltr_el0", CPENC(3,3,C14,C15,7), 0 },
3916 { 0, CPENC(0,0,0,0,0), 0 },
a06ea964
NC
3917};
3918
49eec193
YZ
3919bfd_boolean
3920aarch64_sys_reg_deprecated_p (const aarch64_sys_reg *reg)
3921{
3922 return (reg->flags & F_DEPRECATED) != 0;
3923}
3924
f21cce2c
MW
3925bfd_boolean
3926aarch64_sys_reg_supported_p (const aarch64_feature_set features,
3927 const aarch64_sys_reg *reg)
3928{
3929 if (!(reg->flags & F_ARCHEXT))
3930 return TRUE;
3931
3932 /* PAN. Values are from aarch64_sys_regs. */
3933 if (reg->value == CPEN_(0,C2,3)
3934 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_PAN))
3935 return FALSE;
3936
250aafa4
MW
3937 /* Virtualization host extensions: system registers. */
3938 if ((reg->value == CPENC (3, 4, C2, C0, 1)
3939 || reg->value == CPENC (3, 4, C13, C0, 1)
3940 || reg->value == CPENC (3, 4, C14, C3, 0)
3941 || reg->value == CPENC (3, 4, C14, C3, 1)
3942 || reg->value == CPENC (3, 4, C14, C3, 2))
3943 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_1))
3944 return FALSE;
3945
3946 /* Virtualization host extensions: *_el12 names of *_el1 registers. */
3947 if ((reg->value == CPEN_ (5, C0, 0)
3948 || reg->value == CPEN_ (5, C0, 1)
3949 || reg->value == CPENC (3, 5, C1, C0, 0)
3950 || reg->value == CPENC (3, 5, C1, C0, 2)
3951 || reg->value == CPENC (3, 5, C2, C0, 0)
3952 || reg->value == CPENC (3, 5, C2, C0, 1)
3953 || reg->value == CPENC (3, 5, C2, C0, 2)
3954 || reg->value == CPENC (3, 5, C5, C1, 0)
3955 || reg->value == CPENC (3, 5, C5, C1, 1)
3956 || reg->value == CPENC (3, 5, C5, C2, 0)
3957 || reg->value == CPENC (3, 5, C6, C0, 0)
3958 || reg->value == CPENC (3, 5, C10, C2, 0)
3959 || reg->value == CPENC (3, 5, C10, C3, 0)
3960 || reg->value == CPENC (3, 5, C12, C0, 0)
3961 || reg->value == CPENC (3, 5, C13, C0, 1)
3962 || reg->value == CPENC (3, 5, C14, C1, 0))
3963 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_1))
3964 return FALSE;
3965
3966 /* Virtualization host extensions: *_el02 names of *_el0 registers. */
3967 if ((reg->value == CPENC (3, 5, C14, C2, 0)
3968 || reg->value == CPENC (3, 5, C14, C2, 1)
3969 || reg->value == CPENC (3, 5, C14, C2, 2)
3970 || reg->value == CPENC (3, 5, C14, C3, 0)
3971 || reg->value == CPENC (3, 5, C14, C3, 1)
3972 || reg->value == CPENC (3, 5, C14, C3, 2))
3973 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_1))
63511907 3974 return FALSE;
1a04d1a7
MW
3975
3976 /* ARMv8.2 features. */
6479e48e
MW
3977
3978 /* ID_AA64MMFR2_EL1. */
1a04d1a7
MW
3979 if (reg->value == CPENC (3, 0, C0, C7, 2)
3980 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
250aafa4
MW
3981 return FALSE;
3982
6479e48e
MW
3983 /* PSTATE.UAO. */
3984 if (reg->value == CPEN_ (0, C2, 4)
3985 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
3986 return FALSE;
3987
47f81142
MW
3988 /* RAS extension. */
3989
651657fa
MW
3990 /* ERRIDR_EL1, ERRSELR_EL1, ERXFR_EL1, ERXCTLR_EL1, ERXSTATUS_EL, ERXADDR_EL1,
3991 ERXMISC0_EL1 AND ERXMISC1_EL1. */
47f81142 3992 if ((reg->value == CPENC (3, 0, C5, C3, 0)
651657fa 3993 || reg->value == CPENC (3, 0, C5, C3, 1)
47f81142
MW
3994 || reg->value == CPENC (3, 0, C5, C3, 2)
3995 || reg->value == CPENC (3, 0, C5, C3, 3)
651657fa
MW
3996 || reg->value == CPENC (3, 0, C5, C4, 0)
3997 || reg->value == CPENC (3, 0, C5, C4, 1)
3998 || reg->value == CPENC (3, 0, C5, C4, 2)
3999 || reg->value == CPENC (3, 0, C5, C4, 3)
47f81142
MW
4000 || reg->value == CPENC (3, 0, C5, C5, 0)
4001 || reg->value == CPENC (3, 0, C5, C5, 1))
4002 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_RAS))
4003 return FALSE;
4004
4005 /* VSESR_EL2, DISR_EL1 and VDISR_EL2. */
4006 if ((reg->value == CPENC (3, 4, C5, C2, 3)
4007 || reg->value == CPENC (3, 0, C12, C1, 1)
4008 || reg->value == CPENC (3, 4, C12, C1, 1))
4009 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_RAS))
4010 return FALSE;
4011
55c144e6
MW
4012 /* Statistical Profiling extension. */
4013 if ((reg->value == CPENC (3, 0, C9, C10, 0)
4014 || reg->value == CPENC (3, 0, C9, C10, 1)
4015 || reg->value == CPENC (3, 0, C9, C10, 3)
4016 || reg->value == CPENC (3, 0, C9, C10, 7)
4017 || reg->value == CPENC (3, 0, C9, C9, 0)
4018 || reg->value == CPENC (3, 0, C9, C9, 2)
4019 || reg->value == CPENC (3, 0, C9, C9, 3)
4020 || reg->value == CPENC (3, 0, C9, C9, 4)
4021 || reg->value == CPENC (3, 0, C9, C9, 5)
4022 || reg->value == CPENC (3, 0, C9, C9, 6)
4023 || reg->value == CPENC (3, 0, C9, C9, 7)
4024 || reg->value == CPENC (3, 4, C9, C9, 0)
4025 || reg->value == CPENC (3, 5, C9, C9, 0))
4026 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_PROFILE))
4027 return FALSE;
4028
f21cce2c
MW
4029 return TRUE;
4030}
4031
87b8eed7 4032const aarch64_sys_reg aarch64_pstatefields [] =
a06ea964 4033{
87b8eed7
YZ
4034 { "spsel", 0x05, 0 },
4035 { "daifset", 0x1e, 0 },
4036 { "daifclr", 0x1f, 0 },
f21cce2c 4037 { "pan", 0x04, F_ARCHEXT },
6479e48e 4038 { "uao", 0x03, F_ARCHEXT },
87b8eed7 4039 { 0, CPENC(0,0,0,0,0), 0 },
a06ea964
NC
4040};
4041
f21cce2c
MW
4042bfd_boolean
4043aarch64_pstatefield_supported_p (const aarch64_feature_set features,
4044 const aarch64_sys_reg *reg)
4045{
4046 if (!(reg->flags & F_ARCHEXT))
4047 return TRUE;
4048
4049 /* PAN. Values are from aarch64_pstatefields. */
4050 if (reg->value == 0x04
4051 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_PAN))
4052 return FALSE;
4053
6479e48e
MW
4054 /* UAO. Values are from aarch64_pstatefields. */
4055 if (reg->value == 0x03
4056 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
4057 return FALSE;
4058
f21cce2c
MW
4059 return TRUE;
4060}
4061
a06ea964
NC
4062const aarch64_sys_ins_reg aarch64_sys_regs_ic[] =
4063{
4064 { "ialluis", CPENS(0,C7,C1,0), 0 },
4065 { "iallu", CPENS(0,C7,C5,0), 0 },
ea2deeec 4066 { "ivau", CPENS (3, C7, C5, 1), F_HASXT },
a06ea964
NC
4067 { 0, CPENS(0,0,0,0), 0 }
4068};
4069
4070const aarch64_sys_ins_reg aarch64_sys_regs_dc[] =
4071{
ea2deeec
MW
4072 { "zva", CPENS (3, C7, C4, 1), F_HASXT },
4073 { "ivac", CPENS (0, C7, C6, 1), F_HASXT },
4074 { "isw", CPENS (0, C7, C6, 2), F_HASXT },
4075 { "cvac", CPENS (3, C7, C10, 1), F_HASXT },
4076 { "csw", CPENS (0, C7, C10, 2), F_HASXT },
4077 { "cvau", CPENS (3, C7, C11, 1), F_HASXT },
d6bf7ce6 4078 { "cvap", CPENS (3, C7, C12, 1), F_HASXT | F_ARCHEXT },
ea2deeec
MW
4079 { "civac", CPENS (3, C7, C14, 1), F_HASXT },
4080 { "cisw", CPENS (0, C7, C14, 2), F_HASXT },
a06ea964
NC
4081 { 0, CPENS(0,0,0,0), 0 }
4082};
4083
4084const aarch64_sys_ins_reg aarch64_sys_regs_at[] =
4085{
ea2deeec
MW
4086 { "s1e1r", CPENS (0, C7, C8, 0), F_HASXT },
4087 { "s1e1w", CPENS (0, C7, C8, 1), F_HASXT },
4088 { "s1e0r", CPENS (0, C7, C8, 2), F_HASXT },
4089 { "s1e0w", CPENS (0, C7, C8, 3), F_HASXT },
4090 { "s12e1r", CPENS (4, C7, C8, 4), F_HASXT },
4091 { "s12e1w", CPENS (4, C7, C8, 5), F_HASXT },
4092 { "s12e0r", CPENS (4, C7, C8, 6), F_HASXT },
4093 { "s12e0w", CPENS (4, C7, C8, 7), F_HASXT },
4094 { "s1e2r", CPENS (4, C7, C8, 0), F_HASXT },
4095 { "s1e2w", CPENS (4, C7, C8, 1), F_HASXT },
4096 { "s1e3r", CPENS (6, C7, C8, 0), F_HASXT },
4097 { "s1e3w", CPENS (6, C7, C8, 1), F_HASXT },
22a5455c
MW
4098 { "s1e1rp", CPENS (0, C7, C9, 0), F_HASXT | F_ARCHEXT },
4099 { "s1e1wp", CPENS (0, C7, C9, 1), F_HASXT | F_ARCHEXT },
a06ea964
NC
4100 { 0, CPENS(0,0,0,0), 0 }
4101};
4102
4103const aarch64_sys_ins_reg aarch64_sys_regs_tlbi[] =
4104{
4105 { "vmalle1", CPENS(0,C8,C7,0), 0 },
ea2deeec
MW
4106 { "vae1", CPENS (0, C8, C7, 1), F_HASXT },
4107 { "aside1", CPENS (0, C8, C7, 2), F_HASXT },
4108 { "vaae1", CPENS (0, C8, C7, 3), F_HASXT },
a06ea964 4109 { "vmalle1is", CPENS(0,C8,C3,0), 0 },
ea2deeec
MW
4110 { "vae1is", CPENS (0, C8, C3, 1), F_HASXT },
4111 { "aside1is", CPENS (0, C8, C3, 2), F_HASXT },
4112 { "vaae1is", CPENS (0, C8, C3, 3), F_HASXT },
4113 { "ipas2e1is", CPENS (4, C8, C0, 1), F_HASXT },
4114 { "ipas2le1is",CPENS (4, C8, C0, 5), F_HASXT },
4115 { "ipas2e1", CPENS (4, C8, C4, 1), F_HASXT },
4116 { "ipas2le1", CPENS (4, C8, C4, 5), F_HASXT },
4117 { "vae2", CPENS (4, C8, C7, 1), F_HASXT },
4118 { "vae2is", CPENS (4, C8, C3, 1), F_HASXT },
a06ea964
NC
4119 { "vmalls12e1",CPENS(4,C8,C7,6), 0 },
4120 { "vmalls12e1is",CPENS(4,C8,C3,6), 0 },
ea2deeec
MW
4121 { "vae3", CPENS (6, C8, C7, 1), F_HASXT },
4122 { "vae3is", CPENS (6, C8, C3, 1), F_HASXT },
a06ea964
NC
4123 { "alle2", CPENS(4,C8,C7,0), 0 },
4124 { "alle2is", CPENS(4,C8,C3,0), 0 },
4125 { "alle1", CPENS(4,C8,C7,4), 0 },
4126 { "alle1is", CPENS(4,C8,C3,4), 0 },
4127 { "alle3", CPENS(6,C8,C7,0), 0 },
4128 { "alle3is", CPENS(6,C8,C3,0), 0 },
ea2deeec
MW
4129 { "vale1is", CPENS (0, C8, C3, 5), F_HASXT },
4130 { "vale2is", CPENS (4, C8, C3, 5), F_HASXT },
4131 { "vale3is", CPENS (6, C8, C3, 5), F_HASXT },
4132 { "vaale1is", CPENS (0, C8, C3, 7), F_HASXT },
4133 { "vale1", CPENS (0, C8, C7, 5), F_HASXT },
4134 { "vale2", CPENS (4, C8, C7, 5), F_HASXT },
4135 { "vale3", CPENS (6, C8, C7, 5), F_HASXT },
4136 { "vaale1", CPENS (0, C8, C7, 7), F_HASXT },
a06ea964
NC
4137 { 0, CPENS(0,0,0,0), 0 }
4138};
4139
ea2deeec
MW
4140bfd_boolean
4141aarch64_sys_ins_reg_has_xt (const aarch64_sys_ins_reg *sys_ins_reg)
4142{
4143 return (sys_ins_reg->flags & F_HASXT) != 0;
4144}
4145
d6bf7ce6
MW
4146extern bfd_boolean
4147aarch64_sys_ins_reg_supported_p (const aarch64_feature_set features,
4148 const aarch64_sys_ins_reg *reg)
4149{
4150 if (!(reg->flags & F_ARCHEXT))
4151 return TRUE;
4152
4153 /* DC CVAP. Values are from aarch64_sys_regs_dc. */
4154 if (reg->value == CPENS (3, C7, C12, 1)
4155 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
4156 return FALSE;
4157
63511907
MW
4158 /* AT S1E1RP, AT S1E1WP. Values are from aarch64_sys_regs_at. */
4159 if ((reg->value == CPENS (0, C7, C9, 0)
4160 || reg->value == CPENS (0, C7, C9, 1))
4161 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
4162 return FALSE;
4163
d6bf7ce6
MW
4164 return TRUE;
4165}
4166
a06ea964
NC
4167#undef C0
4168#undef C1
4169#undef C2
4170#undef C3
4171#undef C4
4172#undef C5
4173#undef C6
4174#undef C7
4175#undef C8
4176#undef C9
4177#undef C10
4178#undef C11
4179#undef C12
4180#undef C13
4181#undef C14
4182#undef C15
4183
4bd13cde
NC
4184#define BIT(INSN,BT) (((INSN) >> (BT)) & 1)
4185#define BITS(INSN,HI,LO) (((INSN) >> (LO)) & ((1 << (((HI) - (LO)) + 1)) - 1))
4186
20f55f38 4187static bfd_boolean
4bd13cde
NC
4188verify_ldpsw (const struct aarch64_opcode * opcode ATTRIBUTE_UNUSED,
4189 const aarch64_insn insn)
4190{
4191 int t = BITS (insn, 4, 0);
4192 int n = BITS (insn, 9, 5);
4193 int t2 = BITS (insn, 14, 10);
4194
4195 if (BIT (insn, 23))
4196 {
4197 /* Write back enabled. */
4198 if ((t == n || t2 == n) && n != 31)
4199 return FALSE;
4200 }
4201
4202 if (BIT (insn, 22))
4203 {
4204 /* Load */
4205 if (t == t2)
4206 return FALSE;
4207 }
4208
4209 return TRUE;
4210}
4211
e950b345
RS
4212/* Return true if VALUE cannot be moved into an SVE register using DUP
4213 (with any element size, not just ESIZE) and if using DUPM would
4214 therefore be OK. ESIZE is the number of bytes in the immediate. */
4215
4216bfd_boolean
4217aarch64_sve_dupm_mov_immediate_p (uint64_t uvalue, int esize)
4218{
4219 int64_t svalue = uvalue;
4220 uint64_t upper = (uint64_t) -1 << (esize * 4) << (esize * 4);
4221
4222 if ((uvalue & ~upper) != uvalue && (uvalue | upper) != uvalue)
4223 return FALSE;
4224 if (esize <= 4 || (uint32_t) uvalue == (uint32_t) (uvalue >> 32))
4225 {
4226 svalue = (int32_t) uvalue;
4227 if (esize <= 2 || (uint16_t) uvalue == (uint16_t) (uvalue >> 16))
4228 {
4229 svalue = (int16_t) uvalue;
4230 if (esize == 1 || (uint8_t) uvalue == (uint8_t) (uvalue >> 8))
4231 return FALSE;
4232 }
4233 }
4234 if ((svalue & 0xff) == 0)
4235 svalue /= 256;
4236 return svalue < -128 || svalue >= 128;
4237}
4238
a06ea964
NC
4239/* Include the opcode description table as well as the operand description
4240 table. */
20f55f38 4241#define VERIFIER(x) verify_##x
a06ea964 4242#include "aarch64-tbl.h"
This page took 0.41277 seconds and 4 git commands to generate.