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