Fix generation of AArhc64 instruction table.
[deliverable/binutils-gdb.git] / opcodes / aarch64-opc.c
CommitLineData
a06ea964 1/* aarch64-opc.c -- AArch64 opcode support.
6f2750fe 2 Copyright (C) 2009-2016 Free Software Foundation, Inc.
a06ea964
NC
3 Contributed by ARM Ltd.
4
5 This file is part of the GNU opcodes library.
6
7 This library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 It is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; see the file COPYING3. If not,
19 see <http://www.gnu.org/licenses/>. */
20
21#include "sysdep.h"
22#include <assert.h>
23#include <stdlib.h>
24#include <stdio.h>
25#include <stdint.h>
26#include <stdarg.h>
27#include <inttypes.h>
28
29#include "opintl.h"
30
31#include "aarch64-opc.h"
32
33#ifdef DEBUG_AARCH64
34int debug_dump = FALSE;
35#endif /* DEBUG_AARCH64 */
36
37/* Helper functions to determine which operand to be used to encode/decode
38 the size:Q fields for AdvSIMD instructions. */
39
40static inline bfd_boolean
41vector_qualifier_p (enum aarch64_opnd_qualifier qualifier)
42{
43 return ((qualifier >= AARCH64_OPND_QLF_V_8B
44 && qualifier <= AARCH64_OPND_QLF_V_1Q) ? TRUE
45 : FALSE);
46}
47
48static inline bfd_boolean
49fp_qualifier_p (enum aarch64_opnd_qualifier qualifier)
50{
51 return ((qualifier >= AARCH64_OPND_QLF_S_B
52 && qualifier <= AARCH64_OPND_QLF_S_Q) ? TRUE
53 : FALSE);
54}
55
56enum data_pattern
57{
58 DP_UNKNOWN,
59 DP_VECTOR_3SAME,
60 DP_VECTOR_LONG,
61 DP_VECTOR_WIDE,
62 DP_VECTOR_ACROSS_LANES,
63};
64
65static const char significant_operand_index [] =
66{
67 0, /* DP_UNKNOWN, by default using operand 0. */
68 0, /* DP_VECTOR_3SAME */
69 1, /* DP_VECTOR_LONG */
70 2, /* DP_VECTOR_WIDE */
71 1, /* DP_VECTOR_ACROSS_LANES */
72};
73
74/* Given a sequence of qualifiers in QUALIFIERS, determine and return
75 the data pattern.
76 N.B. QUALIFIERS is a possible sequence of qualifiers each of which
77 corresponds to one of a sequence of operands. */
78
79static enum data_pattern
80get_data_pattern (const aarch64_opnd_qualifier_seq_t qualifiers)
81{
82 if (vector_qualifier_p (qualifiers[0]) == TRUE)
83 {
84 /* e.g. v.4s, v.4s, v.4s
85 or v.4h, v.4h, v.h[3]. */
86 if (qualifiers[0] == qualifiers[1]
87 && vector_qualifier_p (qualifiers[2]) == TRUE
88 && (aarch64_get_qualifier_esize (qualifiers[0])
89 == aarch64_get_qualifier_esize (qualifiers[1]))
90 && (aarch64_get_qualifier_esize (qualifiers[0])
91 == aarch64_get_qualifier_esize (qualifiers[2])))
92 return DP_VECTOR_3SAME;
93 /* e.g. v.8h, v.8b, v.8b.
94 or v.4s, v.4h, v.h[2].
95 or v.8h, v.16b. */
96 if (vector_qualifier_p (qualifiers[1]) == TRUE
97 && aarch64_get_qualifier_esize (qualifiers[0]) != 0
98 && (aarch64_get_qualifier_esize (qualifiers[0])
99 == aarch64_get_qualifier_esize (qualifiers[1]) << 1))
100 return DP_VECTOR_LONG;
101 /* e.g. v.8h, v.8h, v.8b. */
102 if (qualifiers[0] == qualifiers[1]
103 && vector_qualifier_p (qualifiers[2]) == TRUE
104 && aarch64_get_qualifier_esize (qualifiers[0]) != 0
105 && (aarch64_get_qualifier_esize (qualifiers[0])
106 == aarch64_get_qualifier_esize (qualifiers[2]) << 1)
107 && (aarch64_get_qualifier_esize (qualifiers[0])
108 == aarch64_get_qualifier_esize (qualifiers[1])))
109 return DP_VECTOR_WIDE;
110 }
111 else if (fp_qualifier_p (qualifiers[0]) == TRUE)
112 {
113 /* e.g. SADDLV <V><d>, <Vn>.<T>. */
114 if (vector_qualifier_p (qualifiers[1]) == TRUE
115 && qualifiers[2] == AARCH64_OPND_QLF_NIL)
116 return DP_VECTOR_ACROSS_LANES;
117 }
118
119 return DP_UNKNOWN;
120}
121
122/* Select the operand to do the encoding/decoding of the 'size:Q' fields in
123 the AdvSIMD instructions. */
124/* N.B. it is possible to do some optimization that doesn't call
125 get_data_pattern each time when we need to select an operand. We can
126 either buffer the caculated the result or statically generate the data,
127 however, it is not obvious that the optimization will bring significant
128 benefit. */
129
130int
131aarch64_select_operand_for_sizeq_field_coding (const aarch64_opcode *opcode)
132{
133 return
134 significant_operand_index [get_data_pattern (opcode->qualifiers_list[0])];
135}
136\f
137const aarch64_field fields[] =
138{
139 { 0, 0 }, /* NIL. */
140 { 0, 4 }, /* cond2: condition in truly conditional-executed inst. */
141 { 0, 4 }, /* nzcv: flag bit specifier, encoded in the "nzcv" field. */
142 { 5, 5 }, /* defgh: d:e:f:g:h bits in AdvSIMD modified immediate. */
143 { 16, 3 }, /* abc: a:b:c bits in AdvSIMD modified immediate. */
144 { 5, 19 }, /* imm19: e.g. in CBZ. */
145 { 5, 19 }, /* immhi: e.g. in ADRP. */
146 { 29, 2 }, /* immlo: e.g. in ADRP. */
147 { 22, 2 }, /* size: in most AdvSIMD and floating-point instructions. */
148 { 10, 2 }, /* vldst_size: size field in the AdvSIMD load/store inst. */
149 { 29, 1 }, /* op: in AdvSIMD modified immediate instructions. */
150 { 30, 1 }, /* Q: in most AdvSIMD instructions. */
151 { 0, 5 }, /* Rt: in load/store instructions. */
152 { 0, 5 }, /* Rd: in many integer instructions. */
153 { 5, 5 }, /* Rn: in many integer instructions. */
154 { 10, 5 }, /* Rt2: in load/store pair instructions. */
155 { 10, 5 }, /* Ra: in fp instructions. */
156 { 5, 3 }, /* op2: in the system instructions. */
157 { 8, 4 }, /* CRm: in the system instructions. */
158 { 12, 4 }, /* CRn: in the system instructions. */
159 { 16, 3 }, /* op1: in the system instructions. */
160 { 19, 2 }, /* op0: in the system instructions. */
161 { 10, 3 }, /* imm3: in add/sub extended reg instructions. */
162 { 12, 4 }, /* cond: condition flags as a source operand. */
163 { 12, 4 }, /* opcode: in advsimd load/store instructions. */
164 { 12, 4 }, /* cmode: in advsimd modified immediate instructions. */
165 { 13, 3 }, /* asisdlso_opcode: opcode in advsimd ld/st single element. */
166 { 13, 2 }, /* len: in advsimd tbl/tbx instructions. */
167 { 16, 5 }, /* Rm: in ld/st reg offset and some integer inst. */
168 { 16, 5 }, /* Rs: in load/store exclusive instructions. */
169 { 13, 3 }, /* option: in ld/st reg offset + add/sub extended reg inst. */
170 { 12, 1 }, /* S: in load/store reg offset instructions. */
171 { 21, 2 }, /* hw: in move wide constant instructions. */
172 { 22, 2 }, /* opc: in load/store reg offset instructions. */
173 { 23, 1 }, /* opc1: in load/store reg offset instructions. */
174 { 22, 2 }, /* shift: in add/sub reg/imm shifted instructions. */
175 { 22, 2 }, /* type: floating point type field in fp data inst. */
176 { 30, 2 }, /* ldst_size: size field in ld/st reg offset inst. */
177 { 10, 6 }, /* imm6: in add/sub reg shifted instructions. */
178 { 11, 4 }, /* imm4: in advsimd ext and advsimd ins instructions. */
179 { 16, 5 }, /* imm5: in conditional compare (immediate) instructions. */
180 { 15, 7 }, /* imm7: in load/store pair pre/post index instructions. */
181 { 13, 8 }, /* imm8: in floating-point scalar move immediate inst. */
182 { 12, 9 }, /* imm9: in load/store pre/post index instructions. */
183 { 10, 12 }, /* imm12: in ld/st unsigned imm or add/sub shifted inst. */
184 { 5, 14 }, /* imm14: in test bit and branch instructions. */
185 { 5, 16 }, /* imm16: in exception instructions. */
186 { 0, 26 }, /* imm26: in unconditional branch instructions. */
187 { 10, 6 }, /* imms: in bitfield and logical immediate instructions. */
188 { 16, 6 }, /* immr: in bitfield and logical immediate instructions. */
189 { 16, 3 }, /* immb: in advsimd shift by immediate instructions. */
190 { 19, 4 }, /* immh: in advsimd shift by immediate instructions. */
191 { 22, 1 }, /* N: in logical (immediate) instructions. */
192 { 11, 1 }, /* index: in ld/st inst deciding the pre/post-index. */
193 { 24, 1 }, /* index2: in ld/st pair inst deciding the pre/post-index. */
194 { 31, 1 }, /* sf: in integer data processing instructions. */
ee804238 195 { 30, 1 }, /* lse_size: in LSE extension atomic instructions. */
a06ea964
NC
196 { 11, 1 }, /* H: in advsimd scalar x indexed element instructions. */
197 { 21, 1 }, /* L: in advsimd scalar x indexed element instructions. */
198 { 20, 1 }, /* M: in advsimd scalar x indexed element instructions. */
199 { 31, 1 }, /* b5: in the test bit and branch instructions. */
200 { 19, 5 }, /* b40: in the test bit and branch instructions. */
201 { 10, 6 }, /* scale: in the fixed-point scalar to fp converting inst. */
202};
203
204enum aarch64_operand_class
205aarch64_get_operand_class (enum aarch64_opnd type)
206{
207 return aarch64_operands[type].op_class;
208}
209
210const char *
211aarch64_get_operand_name (enum aarch64_opnd type)
212{
213 return aarch64_operands[type].name;
214}
215
216/* Get operand description string.
217 This is usually for the diagnosis purpose. */
218const char *
219aarch64_get_operand_desc (enum aarch64_opnd type)
220{
221 return aarch64_operands[type].desc;
222}
223
224/* Table of all conditional affixes. */
225const aarch64_cond aarch64_conds[16] =
226{
227 {{"eq"}, 0x0},
228 {{"ne"}, 0x1},
229 {{"cs", "hs"}, 0x2},
230 {{"cc", "lo", "ul"}, 0x3},
231 {{"mi"}, 0x4},
232 {{"pl"}, 0x5},
233 {{"vs"}, 0x6},
234 {{"vc"}, 0x7},
235 {{"hi"}, 0x8},
236 {{"ls"}, 0x9},
237 {{"ge"}, 0xa},
238 {{"lt"}, 0xb},
239 {{"gt"}, 0xc},
240 {{"le"}, 0xd},
241 {{"al"}, 0xe},
242 {{"nv"}, 0xf},
243};
244
245const aarch64_cond *
246get_cond_from_value (aarch64_insn value)
247{
248 assert (value < 16);
249 return &aarch64_conds[(unsigned int) value];
250}
251
252const aarch64_cond *
253get_inverted_cond (const aarch64_cond *cond)
254{
255 return &aarch64_conds[cond->value ^ 0x1];
256}
257
258/* Table describing the operand extension/shifting operators; indexed by
259 enum aarch64_modifier_kind.
260
261 The value column provides the most common values for encoding modifiers,
262 which enables table-driven encoding/decoding for the modifiers. */
263const struct aarch64_name_value_pair aarch64_operand_modifiers [] =
264{
265 {"none", 0x0},
266 {"msl", 0x0},
267 {"ror", 0x3},
268 {"asr", 0x2},
269 {"lsr", 0x1},
270 {"lsl", 0x0},
271 {"uxtb", 0x0},
272 {"uxth", 0x1},
273 {"uxtw", 0x2},
274 {"uxtx", 0x3},
275 {"sxtb", 0x4},
276 {"sxth", 0x5},
277 {"sxtw", 0x6},
278 {"sxtx", 0x7},
279 {NULL, 0},
280};
281
282enum aarch64_modifier_kind
283aarch64_get_operand_modifier (const struct aarch64_name_value_pair *desc)
284{
285 return desc - aarch64_operand_modifiers;
286}
287
288aarch64_insn
289aarch64_get_operand_modifier_value (enum aarch64_modifier_kind kind)
290{
291 return aarch64_operand_modifiers[kind].value;
292}
293
294enum aarch64_modifier_kind
295aarch64_get_operand_modifier_from_value (aarch64_insn value,
296 bfd_boolean extend_p)
297{
298 if (extend_p == TRUE)
299 return AARCH64_MOD_UXTB + value;
300 else
301 return AARCH64_MOD_LSL - value;
302}
303
304bfd_boolean
305aarch64_extend_operator_p (enum aarch64_modifier_kind kind)
306{
307 return (kind > AARCH64_MOD_LSL && kind <= AARCH64_MOD_SXTX)
308 ? TRUE : FALSE;
309}
310
311static inline bfd_boolean
312aarch64_shift_operator_p (enum aarch64_modifier_kind kind)
313{
314 return (kind >= AARCH64_MOD_ROR && kind <= AARCH64_MOD_LSL)
315 ? TRUE : FALSE;
316}
317
318const struct aarch64_name_value_pair aarch64_barrier_options[16] =
319{
320 { "#0x00", 0x0 },
321 { "oshld", 0x1 },
322 { "oshst", 0x2 },
323 { "osh", 0x3 },
324 { "#0x04", 0x4 },
325 { "nshld", 0x5 },
326 { "nshst", 0x6 },
327 { "nsh", 0x7 },
328 { "#0x08", 0x8 },
329 { "ishld", 0x9 },
330 { "ishst", 0xa },
331 { "ish", 0xb },
332 { "#0x0c", 0xc },
333 { "ld", 0xd },
334 { "st", 0xe },
335 { "sy", 0xf },
336};
337
9ed608f9
MW
338/* Table describing the operands supported by the aliases of the HINT
339 instruction.
340
341 The name column is the operand that is accepted for the alias. The value
342 column is the hint number of the alias. The list of operands is terminated
343 by NULL in the name column. */
344
345const struct aarch64_name_value_pair aarch64_hint_options[] =
346{
1e6f4800 347 { "csync", 0x11 }, /* PSB CSYNC. */
9ed608f9
MW
348 { NULL, 0x0 },
349};
350
a32c3ff8 351/* op -> op: load = 0 instruction = 1 store = 2
a06ea964
NC
352 l -> level: 1-3
353 t -> temporal: temporal (retained) = 0 non-temporal (streaming) = 1 */
a32c3ff8 354#define B(op,l,t) (((op) << 3) | (((l) - 1) << 1) | (t))
a06ea964
NC
355const struct aarch64_name_value_pair aarch64_prfops[32] =
356{
357 { "pldl1keep", B(0, 1, 0) },
358 { "pldl1strm", B(0, 1, 1) },
359 { "pldl2keep", B(0, 2, 0) },
360 { "pldl2strm", B(0, 2, 1) },
361 { "pldl3keep", B(0, 3, 0) },
362 { "pldl3strm", B(0, 3, 1) },
a1ccaec9
YZ
363 { NULL, 0x06 },
364 { NULL, 0x07 },
a32c3ff8
NC
365 { "plil1keep", B(1, 1, 0) },
366 { "plil1strm", B(1, 1, 1) },
367 { "plil2keep", B(1, 2, 0) },
368 { "plil2strm", B(1, 2, 1) },
369 { "plil3keep", B(1, 3, 0) },
370 { "plil3strm", B(1, 3, 1) },
a1ccaec9
YZ
371 { NULL, 0x0e },
372 { NULL, 0x0f },
a32c3ff8
NC
373 { "pstl1keep", B(2, 1, 0) },
374 { "pstl1strm", B(2, 1, 1) },
375 { "pstl2keep", B(2, 2, 0) },
376 { "pstl2strm", B(2, 2, 1) },
377 { "pstl3keep", B(2, 3, 0) },
378 { "pstl3strm", B(2, 3, 1) },
a1ccaec9
YZ
379 { NULL, 0x16 },
380 { NULL, 0x17 },
381 { NULL, 0x18 },
382 { NULL, 0x19 },
383 { NULL, 0x1a },
384 { NULL, 0x1b },
385 { NULL, 0x1c },
386 { NULL, 0x1d },
387 { NULL, 0x1e },
388 { NULL, 0x1f },
a06ea964
NC
389};
390#undef B
391\f
392/* Utilities on value constraint. */
393
394static inline int
395value_in_range_p (int64_t value, int low, int high)
396{
397 return (value >= low && value <= high) ? 1 : 0;
398}
399
400static inline int
401value_aligned_p (int64_t value, int align)
402{
403 return ((value & (align - 1)) == 0) ? 1 : 0;
404}
405
406/* A signed value fits in a field. */
407static inline int
408value_fit_signed_field_p (int64_t value, unsigned width)
409{
410 assert (width < 32);
411 if (width < sizeof (value) * 8)
412 {
413 int64_t lim = (int64_t)1 << (width - 1);
414 if (value >= -lim && value < lim)
415 return 1;
416 }
417 return 0;
418}
419
420/* An unsigned value fits in a field. */
421static inline int
422value_fit_unsigned_field_p (int64_t value, unsigned width)
423{
424 assert (width < 32);
425 if (width < sizeof (value) * 8)
426 {
427 int64_t lim = (int64_t)1 << width;
428 if (value >= 0 && value < lim)
429 return 1;
430 }
431 return 0;
432}
433
434/* Return 1 if OPERAND is SP or WSP. */
435int
436aarch64_stack_pointer_p (const aarch64_opnd_info *operand)
437{
438 return ((aarch64_get_operand_class (operand->type)
439 == AARCH64_OPND_CLASS_INT_REG)
440 && operand_maybe_stack_pointer (aarch64_operands + operand->type)
441 && operand->reg.regno == 31);
442}
443
444/* Return 1 if OPERAND is XZR or WZP. */
445int
446aarch64_zero_register_p (const aarch64_opnd_info *operand)
447{
448 return ((aarch64_get_operand_class (operand->type)
449 == AARCH64_OPND_CLASS_INT_REG)
450 && !operand_maybe_stack_pointer (aarch64_operands + operand->type)
451 && operand->reg.regno == 31);
452}
453
454/* Return true if the operand *OPERAND that has the operand code
455 OPERAND->TYPE and been qualified by OPERAND->QUALIFIER can be also
456 qualified by the qualifier TARGET. */
457
458static inline int
459operand_also_qualified_p (const struct aarch64_opnd_info *operand,
460 aarch64_opnd_qualifier_t target)
461{
462 switch (operand->qualifier)
463 {
464 case AARCH64_OPND_QLF_W:
465 if (target == AARCH64_OPND_QLF_WSP && aarch64_stack_pointer_p (operand))
466 return 1;
467 break;
468 case AARCH64_OPND_QLF_X:
469 if (target == AARCH64_OPND_QLF_SP && aarch64_stack_pointer_p (operand))
470 return 1;
471 break;
472 case AARCH64_OPND_QLF_WSP:
473 if (target == AARCH64_OPND_QLF_W
474 && operand_maybe_stack_pointer (aarch64_operands + operand->type))
475 return 1;
476 break;
477 case AARCH64_OPND_QLF_SP:
478 if (target == AARCH64_OPND_QLF_X
479 && operand_maybe_stack_pointer (aarch64_operands + operand->type))
480 return 1;
481 break;
482 default:
483 break;
484 }
485
486 return 0;
487}
488
489/* Given qualifier sequence list QSEQ_LIST and the known qualifier KNOWN_QLF
490 for operand KNOWN_IDX, return the expected qualifier for operand IDX.
491
492 Return NIL if more than one expected qualifiers are found. */
493
494aarch64_opnd_qualifier_t
495aarch64_get_expected_qualifier (const aarch64_opnd_qualifier_seq_t *qseq_list,
496 int idx,
497 const aarch64_opnd_qualifier_t known_qlf,
498 int known_idx)
499{
500 int i, saved_i;
501
502 /* Special case.
503
504 When the known qualifier is NIL, we have to assume that there is only
505 one qualifier sequence in the *QSEQ_LIST and return the corresponding
506 qualifier directly. One scenario is that for instruction
507 PRFM <prfop>, [<Xn|SP>, #:lo12:<symbol>]
508 which has only one possible valid qualifier sequence
509 NIL, S_D
510 the caller may pass NIL in KNOWN_QLF to obtain S_D so that it can
511 determine the correct relocation type (i.e. LDST64_LO12) for PRFM.
512
513 Because the qualifier NIL has dual roles in the qualifier sequence:
514 it can mean no qualifier for the operand, or the qualifer sequence is
515 not in use (when all qualifiers in the sequence are NILs), we have to
516 handle this special case here. */
517 if (known_qlf == AARCH64_OPND_NIL)
518 {
519 assert (qseq_list[0][known_idx] == AARCH64_OPND_NIL);
520 return qseq_list[0][idx];
521 }
522
523 for (i = 0, saved_i = -1; i < AARCH64_MAX_QLF_SEQ_NUM; ++i)
524 {
525 if (qseq_list[i][known_idx] == known_qlf)
526 {
527 if (saved_i != -1)
528 /* More than one sequences are found to have KNOWN_QLF at
529 KNOWN_IDX. */
530 return AARCH64_OPND_NIL;
531 saved_i = i;
532 }
533 }
534
535 return qseq_list[saved_i][idx];
536}
537
538enum operand_qualifier_kind
539{
540 OQK_NIL,
541 OQK_OPD_VARIANT,
542 OQK_VALUE_IN_RANGE,
543 OQK_MISC,
544};
545
546/* Operand qualifier description. */
547struct operand_qualifier_data
548{
549 /* The usage of the three data fields depends on the qualifier kind. */
550 int data0;
551 int data1;
552 int data2;
553 /* Description. */
554 const char *desc;
555 /* Kind. */
556 enum operand_qualifier_kind kind;
557};
558
559/* Indexed by the operand qualifier enumerators. */
560struct operand_qualifier_data aarch64_opnd_qualifiers[] =
561{
562 {0, 0, 0, "NIL", OQK_NIL},
563
564 /* Operand variant qualifiers.
565 First 3 fields:
566 element size, number of elements and common value for encoding. */
567
568 {4, 1, 0x0, "w", OQK_OPD_VARIANT},
569 {8, 1, 0x1, "x", OQK_OPD_VARIANT},
570 {4, 1, 0x0, "wsp", OQK_OPD_VARIANT},
571 {8, 1, 0x1, "sp", OQK_OPD_VARIANT},
572
573 {1, 1, 0x0, "b", OQK_OPD_VARIANT},
574 {2, 1, 0x1, "h", OQK_OPD_VARIANT},
575 {4, 1, 0x2, "s", OQK_OPD_VARIANT},
576 {8, 1, 0x3, "d", OQK_OPD_VARIANT},
577 {16, 1, 0x4, "q", OQK_OPD_VARIANT},
578
579 {1, 8, 0x0, "8b", OQK_OPD_VARIANT},
580 {1, 16, 0x1, "16b", OQK_OPD_VARIANT},
3067d3b9 581 {2, 2, 0x0, "2h", OQK_OPD_VARIANT},
a06ea964
NC
582 {2, 4, 0x2, "4h", OQK_OPD_VARIANT},
583 {2, 8, 0x3, "8h", OQK_OPD_VARIANT},
584 {4, 2, 0x4, "2s", OQK_OPD_VARIANT},
585 {4, 4, 0x5, "4s", OQK_OPD_VARIANT},
586 {8, 1, 0x6, "1d", OQK_OPD_VARIANT},
587 {8, 2, 0x7, "2d", OQK_OPD_VARIANT},
588 {16, 1, 0x8, "1q", OQK_OPD_VARIANT},
589
590 /* Qualifiers constraining the value range.
591 First 3 fields:
592 Lower bound, higher bound, unused. */
593
594 {0, 7, 0, "imm_0_7" , OQK_VALUE_IN_RANGE},
595 {0, 15, 0, "imm_0_15", OQK_VALUE_IN_RANGE},
596 {0, 31, 0, "imm_0_31", OQK_VALUE_IN_RANGE},
597 {0, 63, 0, "imm_0_63", OQK_VALUE_IN_RANGE},
598 {1, 32, 0, "imm_1_32", OQK_VALUE_IN_RANGE},
599 {1, 64, 0, "imm_1_64", OQK_VALUE_IN_RANGE},
600
601 /* Qualifiers for miscellaneous purpose.
602 First 3 fields:
603 unused, unused and unused. */
604
605 {0, 0, 0, "lsl", 0},
606 {0, 0, 0, "msl", 0},
607
608 {0, 0, 0, "retrieving", 0},
609};
610
611static inline bfd_boolean
612operand_variant_qualifier_p (aarch64_opnd_qualifier_t qualifier)
613{
614 return (aarch64_opnd_qualifiers[qualifier].kind == OQK_OPD_VARIANT)
615 ? TRUE : FALSE;
616}
617
618static inline bfd_boolean
619qualifier_value_in_range_constraint_p (aarch64_opnd_qualifier_t qualifier)
620{
621 return (aarch64_opnd_qualifiers[qualifier].kind == OQK_VALUE_IN_RANGE)
622 ? TRUE : FALSE;
623}
624
625const char*
626aarch64_get_qualifier_name (aarch64_opnd_qualifier_t qualifier)
627{
628 return aarch64_opnd_qualifiers[qualifier].desc;
629}
630
631/* Given an operand qualifier, return the expected data element size
632 of a qualified operand. */
633unsigned char
634aarch64_get_qualifier_esize (aarch64_opnd_qualifier_t qualifier)
635{
636 assert (operand_variant_qualifier_p (qualifier) == TRUE);
637 return aarch64_opnd_qualifiers[qualifier].data0;
638}
639
640unsigned char
641aarch64_get_qualifier_nelem (aarch64_opnd_qualifier_t qualifier)
642{
643 assert (operand_variant_qualifier_p (qualifier) == TRUE);
644 return aarch64_opnd_qualifiers[qualifier].data1;
645}
646
647aarch64_insn
648aarch64_get_qualifier_standard_value (aarch64_opnd_qualifier_t qualifier)
649{
650 assert (operand_variant_qualifier_p (qualifier) == TRUE);
651 return aarch64_opnd_qualifiers[qualifier].data2;
652}
653
654static int
655get_lower_bound (aarch64_opnd_qualifier_t qualifier)
656{
657 assert (qualifier_value_in_range_constraint_p (qualifier) == TRUE);
658 return aarch64_opnd_qualifiers[qualifier].data0;
659}
660
661static int
662get_upper_bound (aarch64_opnd_qualifier_t qualifier)
663{
664 assert (qualifier_value_in_range_constraint_p (qualifier) == TRUE);
665 return aarch64_opnd_qualifiers[qualifier].data1;
666}
667
668#ifdef DEBUG_AARCH64
669void
670aarch64_verbose (const char *str, ...)
671{
672 va_list ap;
673 va_start (ap, str);
674 printf ("#### ");
675 vprintf (str, ap);
676 printf ("\n");
677 va_end (ap);
678}
679
680static inline void
681dump_qualifier_sequence (const aarch64_opnd_qualifier_t *qualifier)
682{
683 int i;
684 printf ("#### \t");
685 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i, ++qualifier)
686 printf ("%s,", aarch64_get_qualifier_name (*qualifier));
687 printf ("\n");
688}
689
690static void
691dump_match_qualifiers (const struct aarch64_opnd_info *opnd,
692 const aarch64_opnd_qualifier_t *qualifier)
693{
694 int i;
695 aarch64_opnd_qualifier_t curr[AARCH64_MAX_OPND_NUM];
696
697 aarch64_verbose ("dump_match_qualifiers:");
698 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
699 curr[i] = opnd[i].qualifier;
700 dump_qualifier_sequence (curr);
701 aarch64_verbose ("against");
702 dump_qualifier_sequence (qualifier);
703}
704#endif /* DEBUG_AARCH64 */
705
706/* TODO improve this, we can have an extra field at the runtime to
707 store the number of operands rather than calculating it every time. */
708
709int
710aarch64_num_of_operands (const aarch64_opcode *opcode)
711{
712 int i = 0;
713 const enum aarch64_opnd *opnds = opcode->operands;
714 while (opnds[i++] != AARCH64_OPND_NIL)
715 ;
716 --i;
717 assert (i >= 0 && i <= AARCH64_MAX_OPND_NUM);
718 return i;
719}
720
721/* Find the best matched qualifier sequence in *QUALIFIERS_LIST for INST.
722 If succeeds, fill the found sequence in *RET, return 1; otherwise return 0.
723
724 N.B. on the entry, it is very likely that only some operands in *INST
725 have had their qualifiers been established.
726
727 If STOP_AT is not -1, the function will only try to match
728 the qualifier sequence for operands before and including the operand
729 of index STOP_AT; and on success *RET will only be filled with the first
730 (STOP_AT+1) qualifiers.
731
732 A couple examples of the matching algorithm:
733
734 X,W,NIL should match
735 X,W,NIL
736
737 NIL,NIL should match
738 X ,NIL
739
740 Apart from serving the main encoding routine, this can also be called
741 during or after the operand decoding. */
742
743int
744aarch64_find_best_match (const aarch64_inst *inst,
745 const aarch64_opnd_qualifier_seq_t *qualifiers_list,
746 int stop_at, aarch64_opnd_qualifier_t *ret)
747{
748 int found = 0;
749 int i, num_opnds;
750 const aarch64_opnd_qualifier_t *qualifiers;
751
752 num_opnds = aarch64_num_of_operands (inst->opcode);
753 if (num_opnds == 0)
754 {
755 DEBUG_TRACE ("SUCCEED: no operand");
756 return 1;
757 }
758
759 if (stop_at < 0 || stop_at >= num_opnds)
760 stop_at = num_opnds - 1;
761
762 /* For each pattern. */
763 for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i, ++qualifiers_list)
764 {
765 int j;
766 qualifiers = *qualifiers_list;
767
768 /* Start as positive. */
769 found = 1;
770
771 DEBUG_TRACE ("%d", i);
772#ifdef DEBUG_AARCH64
773 if (debug_dump)
774 dump_match_qualifiers (inst->operands, qualifiers);
775#endif
776
777 /* Most opcodes has much fewer patterns in the list.
778 First NIL qualifier indicates the end in the list. */
779 if (empty_qualifier_sequence_p (qualifiers) == TRUE)
780 {
781 DEBUG_TRACE_IF (i == 0, "SUCCEED: empty qualifier list");
782 if (i)
783 found = 0;
784 break;
785 }
786
787 for (j = 0; j < num_opnds && j <= stop_at; ++j, ++qualifiers)
788 {
789 if (inst->operands[j].qualifier == AARCH64_OPND_QLF_NIL)
790 {
791 /* Either the operand does not have qualifier, or the qualifier
792 for the operand needs to be deduced from the qualifier
793 sequence.
794 In the latter case, any constraint checking related with
795 the obtained qualifier should be done later in
796 operand_general_constraint_met_p. */
797 continue;
798 }
799 else if (*qualifiers != inst->operands[j].qualifier)
800 {
801 /* Unless the target qualifier can also qualify the operand
802 (which has already had a non-nil qualifier), non-equal
803 qualifiers are generally un-matched. */
804 if (operand_also_qualified_p (inst->operands + j, *qualifiers))
805 continue;
806 else
807 {
808 found = 0;
809 break;
810 }
811 }
812 else
813 continue; /* Equal qualifiers are certainly matched. */
814 }
815
816 /* Qualifiers established. */
817 if (found == 1)
818 break;
819 }
820
821 if (found == 1)
822 {
823 /* Fill the result in *RET. */
824 int j;
825 qualifiers = *qualifiers_list;
826
827 DEBUG_TRACE ("complete qualifiers using list %d", i);
828#ifdef DEBUG_AARCH64
829 if (debug_dump)
830 dump_qualifier_sequence (qualifiers);
831#endif
832
833 for (j = 0; j <= stop_at; ++j, ++qualifiers)
834 ret[j] = *qualifiers;
835 for (; j < AARCH64_MAX_OPND_NUM; ++j)
836 ret[j] = AARCH64_OPND_QLF_NIL;
837
838 DEBUG_TRACE ("SUCCESS");
839 return 1;
840 }
841
842 DEBUG_TRACE ("FAIL");
843 return 0;
844}
845
846/* Operand qualifier matching and resolving.
847
848 Return 1 if the operand qualifier(s) in *INST match one of the qualifier
849 sequences in INST->OPCODE->qualifiers_list; otherwise return 0.
850
851 if UPDATE_P == TRUE, update the qualifier(s) in *INST after the matching
852 succeeds. */
853
854static int
855match_operands_qualifier (aarch64_inst *inst, bfd_boolean update_p)
856{
857 int i;
858 aarch64_opnd_qualifier_seq_t qualifiers;
859
860 if (!aarch64_find_best_match (inst, inst->opcode->qualifiers_list, -1,
861 qualifiers))
862 {
863 DEBUG_TRACE ("matching FAIL");
864 return 0;
865 }
866
867 /* Update the qualifiers. */
868 if (update_p == TRUE)
869 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
870 {
871 if (inst->opcode->operands[i] == AARCH64_OPND_NIL)
872 break;
873 DEBUG_TRACE_IF (inst->operands[i].qualifier != qualifiers[i],
874 "update %s with %s for operand %d",
875 aarch64_get_qualifier_name (inst->operands[i].qualifier),
876 aarch64_get_qualifier_name (qualifiers[i]), i);
877 inst->operands[i].qualifier = qualifiers[i];
878 }
879
880 DEBUG_TRACE ("matching SUCCESS");
881 return 1;
882}
883
884/* Return TRUE if VALUE is a wide constant that can be moved into a general
885 register by MOVZ.
886
887 IS32 indicates whether value is a 32-bit immediate or not.
888 If SHIFT_AMOUNT is not NULL, on the return of TRUE, the logical left shift
889 amount will be returned in *SHIFT_AMOUNT. */
890
891bfd_boolean
892aarch64_wide_constant_p (int64_t value, int is32, unsigned int *shift_amount)
893{
894 int amount;
895
896 DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 ")", value, value);
897
898 if (is32)
899 {
900 /* Allow all zeros or all ones in top 32-bits, so that
901 32-bit constant expressions like ~0x80000000 are
902 permitted. */
903 uint64_t ext = value;
904 if (ext >> 32 != 0 && ext >> 32 != (uint64_t) 0xffffffff)
905 /* Immediate out of range. */
906 return FALSE;
907 value &= (int64_t) 0xffffffff;
908 }
909
910 /* first, try movz then movn */
911 amount = -1;
912 if ((value & ((int64_t) 0xffff << 0)) == value)
913 amount = 0;
914 else if ((value & ((int64_t) 0xffff << 16)) == value)
915 amount = 16;
916 else if (!is32 && (value & ((int64_t) 0xffff << 32)) == value)
917 amount = 32;
918 else if (!is32 && (value & ((int64_t) 0xffff << 48)) == value)
919 amount = 48;
920
921 if (amount == -1)
922 {
923 DEBUG_TRACE ("exit FALSE with 0x%" PRIx64 "(%" PRIi64 ")", value, value);
924 return FALSE;
925 }
926
927 if (shift_amount != NULL)
928 *shift_amount = amount;
929
930 DEBUG_TRACE ("exit TRUE with amount %d", amount);
931
932 return TRUE;
933}
934
935/* Build the accepted values for immediate logical SIMD instructions.
936
937 The standard encodings of the immediate value are:
938 N imms immr SIMD size R S
939 1 ssssss rrrrrr 64 UInt(rrrrrr) UInt(ssssss)
940 0 0sssss 0rrrrr 32 UInt(rrrrr) UInt(sssss)
941 0 10ssss 00rrrr 16 UInt(rrrr) UInt(ssss)
942 0 110sss 000rrr 8 UInt(rrr) UInt(sss)
943 0 1110ss 0000rr 4 UInt(rr) UInt(ss)
944 0 11110s 00000r 2 UInt(r) UInt(s)
945 where all-ones value of S is reserved.
946
947 Let's call E the SIMD size.
948
949 The immediate value is: S+1 bits '1' rotated to the right by R.
950
951 The total of valid encodings is 64*63 + 32*31 + ... + 2*1 = 5334
952 (remember S != E - 1). */
953
954#define TOTAL_IMM_NB 5334
955
956typedef struct
957{
958 uint64_t imm;
959 aarch64_insn encoding;
960} simd_imm_encoding;
961
962static simd_imm_encoding simd_immediates[TOTAL_IMM_NB];
963
964static int
965simd_imm_encoding_cmp(const void *i1, const void *i2)
966{
967 const simd_imm_encoding *imm1 = (const simd_imm_encoding *)i1;
968 const simd_imm_encoding *imm2 = (const simd_imm_encoding *)i2;
969
970 if (imm1->imm < imm2->imm)
971 return -1;
972 if (imm1->imm > imm2->imm)
973 return +1;
974 return 0;
975}
976
977/* immediate bitfield standard encoding
978 imm13<12> imm13<5:0> imm13<11:6> SIMD size R S
979 1 ssssss rrrrrr 64 rrrrrr ssssss
980 0 0sssss 0rrrrr 32 rrrrr sssss
981 0 10ssss 00rrrr 16 rrrr ssss
982 0 110sss 000rrr 8 rrr sss
983 0 1110ss 0000rr 4 rr ss
984 0 11110s 00000r 2 r s */
985static inline int
986encode_immediate_bitfield (int is64, uint32_t s, uint32_t r)
987{
988 return (is64 << 12) | (r << 6) | s;
989}
990
991static void
992build_immediate_table (void)
993{
994 uint32_t log_e, e, s, r, s_mask;
995 uint64_t mask, imm;
996 int nb_imms;
997 int is64;
998
999 nb_imms = 0;
1000 for (log_e = 1; log_e <= 6; log_e++)
1001 {
1002 /* Get element size. */
1003 e = 1u << log_e;
1004 if (log_e == 6)
1005 {
1006 is64 = 1;
1007 mask = 0xffffffffffffffffull;
1008 s_mask = 0;
1009 }
1010 else
1011 {
1012 is64 = 0;
1013 mask = (1ull << e) - 1;
1014 /* log_e s_mask
1015 1 ((1 << 4) - 1) << 2 = 111100
1016 2 ((1 << 3) - 1) << 3 = 111000
1017 3 ((1 << 2) - 1) << 4 = 110000
1018 4 ((1 << 1) - 1) << 5 = 100000
1019 5 ((1 << 0) - 1) << 6 = 000000 */
1020 s_mask = ((1u << (5 - log_e)) - 1) << (log_e + 1);
1021 }
1022 for (s = 0; s < e - 1; s++)
1023 for (r = 0; r < e; r++)
1024 {
1025 /* s+1 consecutive bits to 1 (s < 63) */
1026 imm = (1ull << (s + 1)) - 1;
1027 /* rotate right by r */
1028 if (r != 0)
1029 imm = (imm >> r) | ((imm << (e - r)) & mask);
1030 /* replicate the constant depending on SIMD size */
1031 switch (log_e)
1032 {
1033 case 1: imm = (imm << 2) | imm;
1034 case 2: imm = (imm << 4) | imm;
1035 case 3: imm = (imm << 8) | imm;
1036 case 4: imm = (imm << 16) | imm;
1037 case 5: imm = (imm << 32) | imm;
1038 case 6: break;
1039 default: abort ();
1040 }
1041 simd_immediates[nb_imms].imm = imm;
1042 simd_immediates[nb_imms].encoding =
1043 encode_immediate_bitfield(is64, s | s_mask, r);
1044 nb_imms++;
1045 }
1046 }
1047 assert (nb_imms == TOTAL_IMM_NB);
1048 qsort(simd_immediates, nb_imms,
1049 sizeof(simd_immediates[0]), simd_imm_encoding_cmp);
1050}
1051
1052/* Return TRUE if VALUE is a valid logical immediate, i.e. bitmask, that can
1053 be accepted by logical (immediate) instructions
1054 e.g. ORR <Xd|SP>, <Xn>, #<imm>.
1055
1056 IS32 indicates whether or not VALUE is a 32-bit immediate.
1057 If ENCODING is not NULL, on the return of TRUE, the standard encoding for
1058 VALUE will be returned in *ENCODING. */
1059
1060bfd_boolean
1061aarch64_logical_immediate_p (uint64_t value, int is32, aarch64_insn *encoding)
1062{
1063 simd_imm_encoding imm_enc;
1064 const simd_imm_encoding *imm_encoding;
1065 static bfd_boolean initialized = FALSE;
1066
1067 DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 "), is32: %d", value,
1068 value, is32);
1069
1070 if (initialized == FALSE)
1071 {
1072 build_immediate_table ();
1073 initialized = TRUE;
1074 }
1075
1076 if (is32)
1077 {
1078 /* Allow all zeros or all ones in top 32-bits, so that
1079 constant expressions like ~1 are permitted. */
1080 if (value >> 32 != 0 && value >> 32 != 0xffffffff)
7e105031
NC
1081 return FALSE;
1082
a06ea964
NC
1083 /* Replicate the 32 lower bits to the 32 upper bits. */
1084 value &= 0xffffffff;
1085 value |= value << 32;
1086 }
1087
1088 imm_enc.imm = value;
1089 imm_encoding = (const simd_imm_encoding *)
1090 bsearch(&imm_enc, simd_immediates, TOTAL_IMM_NB,
1091 sizeof(simd_immediates[0]), simd_imm_encoding_cmp);
1092 if (imm_encoding == NULL)
1093 {
1094 DEBUG_TRACE ("exit with FALSE");
1095 return FALSE;
1096 }
1097 if (encoding != NULL)
1098 *encoding = imm_encoding->encoding;
1099 DEBUG_TRACE ("exit with TRUE");
1100 return TRUE;
1101}
1102
1103/* If 64-bit immediate IMM is in the format of
1104 "aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh",
1105 where a, b, c, d, e, f, g and h are independently 0 or 1, return an integer
1106 of value "abcdefgh". Otherwise return -1. */
1107int
1108aarch64_shrink_expanded_imm8 (uint64_t imm)
1109{
1110 int i, ret;
1111 uint32_t byte;
1112
1113 ret = 0;
1114 for (i = 0; i < 8; i++)
1115 {
1116 byte = (imm >> (8 * i)) & 0xff;
1117 if (byte == 0xff)
1118 ret |= 1 << i;
1119 else if (byte != 0x00)
1120 return -1;
1121 }
1122 return ret;
1123}
1124
1125/* Utility inline functions for operand_general_constraint_met_p. */
1126
1127static inline void
1128set_error (aarch64_operand_error *mismatch_detail,
1129 enum aarch64_operand_error_kind kind, int idx,
1130 const char* error)
1131{
1132 if (mismatch_detail == NULL)
1133 return;
1134 mismatch_detail->kind = kind;
1135 mismatch_detail->index = idx;
1136 mismatch_detail->error = error;
1137}
1138
4e50d5f8
YZ
1139static inline void
1140set_syntax_error (aarch64_operand_error *mismatch_detail, int idx,
1141 const char* error)
1142{
1143 if (mismatch_detail == NULL)
1144 return;
1145 set_error (mismatch_detail, AARCH64_OPDE_SYNTAX_ERROR, idx, error);
1146}
1147
a06ea964
NC
1148static inline void
1149set_out_of_range_error (aarch64_operand_error *mismatch_detail,
1150 int idx, int lower_bound, int upper_bound,
1151 const char* error)
1152{
1153 if (mismatch_detail == NULL)
1154 return;
1155 set_error (mismatch_detail, AARCH64_OPDE_OUT_OF_RANGE, idx, error);
1156 mismatch_detail->data[0] = lower_bound;
1157 mismatch_detail->data[1] = upper_bound;
1158}
1159
1160static inline void
1161set_imm_out_of_range_error (aarch64_operand_error *mismatch_detail,
1162 int idx, int lower_bound, int upper_bound)
1163{
1164 if (mismatch_detail == NULL)
1165 return;
1166 set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1167 _("immediate value"));
1168}
1169
1170static inline void
1171set_offset_out_of_range_error (aarch64_operand_error *mismatch_detail,
1172 int idx, int lower_bound, int upper_bound)
1173{
1174 if (mismatch_detail == NULL)
1175 return;
1176 set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1177 _("immediate offset"));
1178}
1179
1180static inline void
1181set_regno_out_of_range_error (aarch64_operand_error *mismatch_detail,
1182 int idx, int lower_bound, int upper_bound)
1183{
1184 if (mismatch_detail == NULL)
1185 return;
1186 set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1187 _("register number"));
1188}
1189
1190static inline void
1191set_elem_idx_out_of_range_error (aarch64_operand_error *mismatch_detail,
1192 int idx, int lower_bound, int upper_bound)
1193{
1194 if (mismatch_detail == NULL)
1195 return;
1196 set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1197 _("register element index"));
1198}
1199
1200static inline void
1201set_sft_amount_out_of_range_error (aarch64_operand_error *mismatch_detail,
1202 int idx, int lower_bound, int upper_bound)
1203{
1204 if (mismatch_detail == NULL)
1205 return;
1206 set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1207 _("shift amount"));
1208}
1209
1210static inline void
1211set_unaligned_error (aarch64_operand_error *mismatch_detail, int idx,
1212 int alignment)
1213{
1214 if (mismatch_detail == NULL)
1215 return;
1216 set_error (mismatch_detail, AARCH64_OPDE_UNALIGNED, idx, NULL);
1217 mismatch_detail->data[0] = alignment;
1218}
1219
1220static inline void
1221set_reg_list_error (aarch64_operand_error *mismatch_detail, int idx,
1222 int expected_num)
1223{
1224 if (mismatch_detail == NULL)
1225 return;
1226 set_error (mismatch_detail, AARCH64_OPDE_REG_LIST, idx, NULL);
1227 mismatch_detail->data[0] = expected_num;
1228}
1229
1230static inline void
1231set_other_error (aarch64_operand_error *mismatch_detail, int idx,
1232 const char* error)
1233{
1234 if (mismatch_detail == NULL)
1235 return;
1236 set_error (mismatch_detail, AARCH64_OPDE_OTHER_ERROR, idx, error);
1237}
1238
1239/* General constraint checking based on operand code.
1240
1241 Return 1 if OPNDS[IDX] meets the general constraint of operand code TYPE
1242 as the IDXth operand of opcode OPCODE. Otherwise return 0.
1243
1244 This function has to be called after the qualifiers for all operands
1245 have been resolved.
1246
1247 Mismatching error message is returned in *MISMATCH_DETAIL upon request,
1248 i.e. when MISMATCH_DETAIL is non-NULL. This avoids the generation
1249 of error message during the disassembling where error message is not
1250 wanted. We avoid the dynamic construction of strings of error messages
1251 here (i.e. in libopcodes), as it is costly and complicated; instead, we
1252 use a combination of error code, static string and some integer data to
1253 represent an error. */
1254
1255static int
1256operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
1257 enum aarch64_opnd type,
1258 const aarch64_opcode *opcode,
1259 aarch64_operand_error *mismatch_detail)
1260{
1261 unsigned num;
1262 unsigned char size;
1263 int64_t imm;
1264 const aarch64_opnd_info *opnd = opnds + idx;
1265 aarch64_opnd_qualifier_t qualifier = opnd->qualifier;
1266
1267 assert (opcode->operands[idx] == opnd->type && opnd->type == type);
1268
1269 switch (aarch64_operands[type].op_class)
1270 {
1271 case AARCH64_OPND_CLASS_INT_REG:
ee804238
JW
1272 /* Check pair reg constraints for cas* instructions. */
1273 if (type == AARCH64_OPND_PAIRREG)
1274 {
1275 assert (idx == 1 || idx == 3);
1276 if (opnds[idx - 1].reg.regno % 2 != 0)
1277 {
1278 set_syntax_error (mismatch_detail, idx - 1,
1279 _("reg pair must start from even reg"));
1280 return 0;
1281 }
1282 if (opnds[idx].reg.regno != opnds[idx - 1].reg.regno + 1)
1283 {
1284 set_syntax_error (mismatch_detail, idx,
1285 _("reg pair must be contiguous"));
1286 return 0;
1287 }
1288 break;
1289 }
1290
a06ea964
NC
1291 /* <Xt> may be optional in some IC and TLBI instructions. */
1292 if (type == AARCH64_OPND_Rt_SYS)
1293 {
1294 assert (idx == 1 && (aarch64_get_operand_class (opnds[0].type)
1295 == AARCH64_OPND_CLASS_SYSTEM));
ea2deeec
MW
1296 if (opnds[1].present
1297 && !aarch64_sys_ins_reg_has_xt (opnds[0].sysins_op))
a06ea964
NC
1298 {
1299 set_other_error (mismatch_detail, idx, _("extraneous register"));
1300 return 0;
1301 }
ea2deeec
MW
1302 if (!opnds[1].present
1303 && aarch64_sys_ins_reg_has_xt (opnds[0].sysins_op))
a06ea964
NC
1304 {
1305 set_other_error (mismatch_detail, idx, _("missing register"));
1306 return 0;
1307 }
1308 }
1309 switch (qualifier)
1310 {
1311 case AARCH64_OPND_QLF_WSP:
1312 case AARCH64_OPND_QLF_SP:
1313 if (!aarch64_stack_pointer_p (opnd))
1314 {
1315 set_other_error (mismatch_detail, idx,
1316 _("stack pointer register expected"));
1317 return 0;
1318 }
1319 break;
1320 default:
1321 break;
1322 }
1323 break;
1324
68a64283
YZ
1325 case AARCH64_OPND_CLASS_COND:
1326 if (type == AARCH64_OPND_COND1
1327 && (opnds[idx].cond->value & 0xe) == 0xe)
1328 {
1329 /* Not allow AL or NV. */
1330 set_syntax_error (mismatch_detail, idx, NULL);
1331 }
1332 break;
1333
a06ea964
NC
1334 case AARCH64_OPND_CLASS_ADDRESS:
1335 /* Check writeback. */
1336 switch (opcode->iclass)
1337 {
1338 case ldst_pos:
1339 case ldst_unscaled:
1340 case ldstnapair_offs:
1341 case ldstpair_off:
1342 case ldst_unpriv:
1343 if (opnd->addr.writeback == 1)
1344 {
4e50d5f8
YZ
1345 set_syntax_error (mismatch_detail, idx,
1346 _("unexpected address writeback"));
a06ea964
NC
1347 return 0;
1348 }
1349 break;
1350 case ldst_imm9:
1351 case ldstpair_indexed:
1352 case asisdlsep:
1353 case asisdlsop:
1354 if (opnd->addr.writeback == 0)
1355 {
4e50d5f8
YZ
1356 set_syntax_error (mismatch_detail, idx,
1357 _("address writeback expected"));
a06ea964
NC
1358 return 0;
1359 }
1360 break;
1361 default:
1362 assert (opnd->addr.writeback == 0);
1363 break;
1364 }
1365 switch (type)
1366 {
1367 case AARCH64_OPND_ADDR_SIMM7:
1368 /* Scaled signed 7 bits immediate offset. */
1369 /* Get the size of the data element that is accessed, which may be
1370 different from that of the source register size,
1371 e.g. in strb/ldrb. */
1372 size = aarch64_get_qualifier_esize (opnd->qualifier);
1373 if (!value_in_range_p (opnd->addr.offset.imm, -64 * size, 63 * size))
1374 {
1375 set_offset_out_of_range_error (mismatch_detail, idx,
1376 -64 * size, 63 * size);
1377 return 0;
1378 }
1379 if (!value_aligned_p (opnd->addr.offset.imm, size))
1380 {
1381 set_unaligned_error (mismatch_detail, idx, size);
1382 return 0;
1383 }
1384 break;
1385 case AARCH64_OPND_ADDR_SIMM9:
1386 /* Unscaled signed 9 bits immediate offset. */
1387 if (!value_in_range_p (opnd->addr.offset.imm, -256, 255))
1388 {
1389 set_offset_out_of_range_error (mismatch_detail, idx, -256, 255);
1390 return 0;
1391 }
1392 break;
1393
1394 case AARCH64_OPND_ADDR_SIMM9_2:
1395 /* Unscaled signed 9 bits immediate offset, which has to be negative
1396 or unaligned. */
1397 size = aarch64_get_qualifier_esize (qualifier);
1398 if ((value_in_range_p (opnd->addr.offset.imm, 0, 255)
1399 && !value_aligned_p (opnd->addr.offset.imm, size))
1400 || value_in_range_p (opnd->addr.offset.imm, -256, -1))
1401 return 1;
1402 set_other_error (mismatch_detail, idx,
1403 _("negative or unaligned offset expected"));
1404 return 0;
1405
1406 case AARCH64_OPND_SIMD_ADDR_POST:
1407 /* AdvSIMD load/store multiple structures, post-index. */
1408 assert (idx == 1);
1409 if (opnd->addr.offset.is_reg)
1410 {
1411 if (value_in_range_p (opnd->addr.offset.regno, 0, 30))
1412 return 1;
1413 else
1414 {
1415 set_other_error (mismatch_detail, idx,
1416 _("invalid register offset"));
1417 return 0;
1418 }
1419 }
1420 else
1421 {
1422 const aarch64_opnd_info *prev = &opnds[idx-1];
1423 unsigned num_bytes; /* total number of bytes transferred. */
1424 /* The opcode dependent area stores the number of elements in
1425 each structure to be loaded/stored. */
1426 int is_ld1r = get_opcode_dependent_value (opcode) == 1;
1427 if (opcode->operands[0] == AARCH64_OPND_LVt_AL)
1428 /* Special handling of loading single structure to all lane. */
1429 num_bytes = (is_ld1r ? 1 : prev->reglist.num_regs)
1430 * aarch64_get_qualifier_esize (prev->qualifier);
1431 else
1432 num_bytes = prev->reglist.num_regs
1433 * aarch64_get_qualifier_esize (prev->qualifier)
1434 * aarch64_get_qualifier_nelem (prev->qualifier);
1435 if ((int) num_bytes != opnd->addr.offset.imm)
1436 {
1437 set_other_error (mismatch_detail, idx,
1438 _("invalid post-increment amount"));
1439 return 0;
1440 }
1441 }
1442 break;
1443
1444 case AARCH64_OPND_ADDR_REGOFF:
1445 /* Get the size of the data element that is accessed, which may be
1446 different from that of the source register size,
1447 e.g. in strb/ldrb. */
1448 size = aarch64_get_qualifier_esize (opnd->qualifier);
1449 /* It is either no shift or shift by the binary logarithm of SIZE. */
1450 if (opnd->shifter.amount != 0
1451 && opnd->shifter.amount != (int)get_logsz (size))
1452 {
1453 set_other_error (mismatch_detail, idx,
1454 _("invalid shift amount"));
1455 return 0;
1456 }
1457 /* Only UXTW, LSL, SXTW and SXTX are the accepted extending
1458 operators. */
1459 switch (opnd->shifter.kind)
1460 {
1461 case AARCH64_MOD_UXTW:
1462 case AARCH64_MOD_LSL:
1463 case AARCH64_MOD_SXTW:
1464 case AARCH64_MOD_SXTX: break;
1465 default:
1466 set_other_error (mismatch_detail, idx,
1467 _("invalid extend/shift operator"));
1468 return 0;
1469 }
1470 break;
1471
1472 case AARCH64_OPND_ADDR_UIMM12:
1473 imm = opnd->addr.offset.imm;
1474 /* Get the size of the data element that is accessed, which may be
1475 different from that of the source register size,
1476 e.g. in strb/ldrb. */
1477 size = aarch64_get_qualifier_esize (qualifier);
1478 if (!value_in_range_p (opnd->addr.offset.imm, 0, 4095 * size))
1479 {
1480 set_offset_out_of_range_error (mismatch_detail, idx,
1481 0, 4095 * size);
1482 return 0;
1483 }
9de794e1 1484 if (!value_aligned_p (opnd->addr.offset.imm, size))
a06ea964
NC
1485 {
1486 set_unaligned_error (mismatch_detail, idx, size);
1487 return 0;
1488 }
1489 break;
1490
1491 case AARCH64_OPND_ADDR_PCREL14:
1492 case AARCH64_OPND_ADDR_PCREL19:
1493 case AARCH64_OPND_ADDR_PCREL21:
1494 case AARCH64_OPND_ADDR_PCREL26:
1495 imm = opnd->imm.value;
1496 if (operand_need_shift_by_two (get_operand_from_code (type)))
1497 {
1498 /* The offset value in a PC-relative branch instruction is alway
1499 4-byte aligned and is encoded without the lowest 2 bits. */
1500 if (!value_aligned_p (imm, 4))
1501 {
1502 set_unaligned_error (mismatch_detail, idx, 4);
1503 return 0;
1504 }
1505 /* Right shift by 2 so that we can carry out the following check
1506 canonically. */
1507 imm >>= 2;
1508 }
1509 size = get_operand_fields_width (get_operand_from_code (type));
1510 if (!value_fit_signed_field_p (imm, size))
1511 {
1512 set_other_error (mismatch_detail, idx,
1513 _("immediate out of range"));
1514 return 0;
1515 }
1516 break;
1517
1518 default:
1519 break;
1520 }
1521 break;
1522
1523 case AARCH64_OPND_CLASS_SIMD_REGLIST:
1524 /* The opcode dependent area stores the number of elements in
1525 each structure to be loaded/stored. */
1526 num = get_opcode_dependent_value (opcode);
1527 switch (type)
1528 {
1529 case AARCH64_OPND_LVt:
1530 assert (num >= 1 && num <= 4);
1531 /* Unless LD1/ST1, the number of registers should be equal to that
1532 of the structure elements. */
1533 if (num != 1 && opnd->reglist.num_regs != num)
1534 {
1535 set_reg_list_error (mismatch_detail, idx, num);
1536 return 0;
1537 }
1538 break;
1539 case AARCH64_OPND_LVt_AL:
1540 case AARCH64_OPND_LEt:
1541 assert (num >= 1 && num <= 4);
1542 /* The number of registers should be equal to that of the structure
1543 elements. */
1544 if (opnd->reglist.num_regs != num)
1545 {
1546 set_reg_list_error (mismatch_detail, idx, num);
1547 return 0;
1548 }
1549 break;
1550 default:
1551 break;
1552 }
1553 break;
1554
1555 case AARCH64_OPND_CLASS_IMMEDIATE:
1556 /* Constraint check on immediate operand. */
1557 imm = opnd->imm.value;
1558 /* E.g. imm_0_31 constrains value to be 0..31. */
1559 if (qualifier_value_in_range_constraint_p (qualifier)
1560 && !value_in_range_p (imm, get_lower_bound (qualifier),
1561 get_upper_bound (qualifier)))
1562 {
1563 set_imm_out_of_range_error (mismatch_detail, idx,
1564 get_lower_bound (qualifier),
1565 get_upper_bound (qualifier));
1566 return 0;
1567 }
1568
1569 switch (type)
1570 {
1571 case AARCH64_OPND_AIMM:
1572 if (opnd->shifter.kind != AARCH64_MOD_LSL)
1573 {
1574 set_other_error (mismatch_detail, idx,
1575 _("invalid shift operator"));
1576 return 0;
1577 }
1578 if (opnd->shifter.amount != 0 && opnd->shifter.amount != 12)
1579 {
1580 set_other_error (mismatch_detail, idx,
1581 _("shift amount expected to be 0 or 12"));
1582 return 0;
1583 }
1584 if (!value_fit_unsigned_field_p (opnd->imm.value, 12))
1585 {
1586 set_other_error (mismatch_detail, idx,
1587 _("immediate out of range"));
1588 return 0;
1589 }
1590 break;
1591
1592 case AARCH64_OPND_HALF:
1593 assert (idx == 1 && opnds[0].type == AARCH64_OPND_Rd);
1594 if (opnd->shifter.kind != AARCH64_MOD_LSL)
1595 {
1596 set_other_error (mismatch_detail, idx,
1597 _("invalid shift operator"));
1598 return 0;
1599 }
1600 size = aarch64_get_qualifier_esize (opnds[0].qualifier);
1601 if (!value_aligned_p (opnd->shifter.amount, 16))
1602 {
1603 set_other_error (mismatch_detail, idx,
1604 _("shift amount should be a multiple of 16"));
1605 return 0;
1606 }
1607 if (!value_in_range_p (opnd->shifter.amount, 0, size * 8 - 16))
1608 {
1609 set_sft_amount_out_of_range_error (mismatch_detail, idx,
1610 0, size * 8 - 16);
1611 return 0;
1612 }
1613 if (opnd->imm.value < 0)
1614 {
1615 set_other_error (mismatch_detail, idx,
1616 _("negative immediate value not allowed"));
1617 return 0;
1618 }
1619 if (!value_fit_unsigned_field_p (opnd->imm.value, 16))
1620 {
1621 set_other_error (mismatch_detail, idx,
1622 _("immediate out of range"));
1623 return 0;
1624 }
1625 break;
1626
1627 case AARCH64_OPND_IMM_MOV:
1628 {
1629 int is32 = aarch64_get_qualifier_esize (opnds[0].qualifier) == 4;
1630 imm = opnd->imm.value;
1631 assert (idx == 1);
1632 switch (opcode->op)
1633 {
1634 case OP_MOV_IMM_WIDEN:
1635 imm = ~imm;
1636 /* Fall through... */
1637 case OP_MOV_IMM_WIDE:
1638 if (!aarch64_wide_constant_p (imm, is32, NULL))
1639 {
1640 set_other_error (mismatch_detail, idx,
1641 _("immediate out of range"));
1642 return 0;
1643 }
1644 break;
1645 case OP_MOV_IMM_LOG:
1646 if (!aarch64_logical_immediate_p (imm, is32, NULL))
1647 {
1648 set_other_error (mismatch_detail, idx,
1649 _("immediate out of range"));
1650 return 0;
1651 }
1652 break;
1653 default:
1654 assert (0);
1655 return 0;
1656 }
1657 }
1658 break;
1659
1660 case AARCH64_OPND_NZCV:
1661 case AARCH64_OPND_CCMP_IMM:
1662 case AARCH64_OPND_EXCEPTION:
1663 case AARCH64_OPND_UIMM4:
1664 case AARCH64_OPND_UIMM7:
1665 case AARCH64_OPND_UIMM3_OP1:
1666 case AARCH64_OPND_UIMM3_OP2:
1667 size = get_operand_fields_width (get_operand_from_code (type));
1668 assert (size < 32);
1669 if (!value_fit_unsigned_field_p (opnd->imm.value, size))
1670 {
1671 set_imm_out_of_range_error (mismatch_detail, idx, 0,
1672 (1 << size) - 1);
1673 return 0;
1674 }
1675 break;
1676
1677 case AARCH64_OPND_WIDTH:
d685192a 1678 assert (idx > 1 && opnds[idx-1].type == AARCH64_OPND_IMM
a06ea964
NC
1679 && opnds[0].type == AARCH64_OPND_Rd);
1680 size = get_upper_bound (qualifier);
1681 if (opnd->imm.value + opnds[idx-1].imm.value > size)
1682 /* lsb+width <= reg.size */
1683 {
1684 set_imm_out_of_range_error (mismatch_detail, idx, 1,
1685 size - opnds[idx-1].imm.value);
1686 return 0;
1687 }
1688 break;
1689
1690 case AARCH64_OPND_LIMM:
1691 {
1692 int is32 = opnds[0].qualifier == AARCH64_OPND_QLF_W;
1693 uint64_t uimm = opnd->imm.value;
1694 if (opcode->op == OP_BIC)
1695 uimm = ~uimm;
1696 if (aarch64_logical_immediate_p (uimm, is32, NULL) == FALSE)
1697 {
1698 set_other_error (mismatch_detail, idx,
1699 _("immediate out of range"));
1700 return 0;
1701 }
1702 }
1703 break;
1704
1705 case AARCH64_OPND_IMM0:
1706 case AARCH64_OPND_FPIMM0:
1707 if (opnd->imm.value != 0)
1708 {
1709 set_other_error (mismatch_detail, idx,
1710 _("immediate zero expected"));
1711 return 0;
1712 }
1713 break;
1714
1715 case AARCH64_OPND_SHLL_IMM:
1716 assert (idx == 2);
1717 size = 8 * aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
1718 if (opnd->imm.value != size)
1719 {
1720 set_other_error (mismatch_detail, idx,
1721 _("invalid shift amount"));
1722 return 0;
1723 }
1724 break;
1725
1726 case AARCH64_OPND_IMM_VLSL:
1727 size = aarch64_get_qualifier_esize (qualifier);
1728 if (!value_in_range_p (opnd->imm.value, 0, size * 8 - 1))
1729 {
1730 set_imm_out_of_range_error (mismatch_detail, idx, 0,
1731 size * 8 - 1);
1732 return 0;
1733 }
1734 break;
1735
1736 case AARCH64_OPND_IMM_VLSR:
1737 size = aarch64_get_qualifier_esize (qualifier);
1738 if (!value_in_range_p (opnd->imm.value, 1, size * 8))
1739 {
1740 set_imm_out_of_range_error (mismatch_detail, idx, 1, size * 8);
1741 return 0;
1742 }
1743 break;
1744
1745 case AARCH64_OPND_SIMD_IMM:
1746 case AARCH64_OPND_SIMD_IMM_SFT:
1747 /* Qualifier check. */
1748 switch (qualifier)
1749 {
1750 case AARCH64_OPND_QLF_LSL:
1751 if (opnd->shifter.kind != AARCH64_MOD_LSL)
1752 {
1753 set_other_error (mismatch_detail, idx,
1754 _("invalid shift operator"));
1755 return 0;
1756 }
1757 break;
1758 case AARCH64_OPND_QLF_MSL:
1759 if (opnd->shifter.kind != AARCH64_MOD_MSL)
1760 {
1761 set_other_error (mismatch_detail, idx,
1762 _("invalid shift operator"));
1763 return 0;
1764 }
1765 break;
1766 case AARCH64_OPND_QLF_NIL:
1767 if (opnd->shifter.kind != AARCH64_MOD_NONE)
1768 {
1769 set_other_error (mismatch_detail, idx,
1770 _("shift is not permitted"));
1771 return 0;
1772 }
1773 break;
1774 default:
1775 assert (0);
1776 return 0;
1777 }
1778 /* Is the immediate valid? */
1779 assert (idx == 1);
1780 if (aarch64_get_qualifier_esize (opnds[0].qualifier) != 8)
1781 {
d2865ed3
YZ
1782 /* uimm8 or simm8 */
1783 if (!value_in_range_p (opnd->imm.value, -128, 255))
a06ea964 1784 {
d2865ed3 1785 set_imm_out_of_range_error (mismatch_detail, idx, -128, 255);
a06ea964
NC
1786 return 0;
1787 }
1788 }
1789 else if (aarch64_shrink_expanded_imm8 (opnd->imm.value) < 0)
1790 {
1791 /* uimm64 is not
1792 'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeee
1793 ffffffffgggggggghhhhhhhh'. */
1794 set_other_error (mismatch_detail, idx,
1795 _("invalid value for immediate"));
1796 return 0;
1797 }
1798 /* Is the shift amount valid? */
1799 switch (opnd->shifter.kind)
1800 {
1801 case AARCH64_MOD_LSL:
1802 size = aarch64_get_qualifier_esize (opnds[0].qualifier);
f5555712 1803 if (!value_in_range_p (opnd->shifter.amount, 0, (size - 1) * 8))
a06ea964 1804 {
f5555712
YZ
1805 set_sft_amount_out_of_range_error (mismatch_detail, idx, 0,
1806 (size - 1) * 8);
a06ea964
NC
1807 return 0;
1808 }
f5555712 1809 if (!value_aligned_p (opnd->shifter.amount, 8))
a06ea964 1810 {
f5555712 1811 set_unaligned_error (mismatch_detail, idx, 8);
a06ea964
NC
1812 return 0;
1813 }
1814 break;
1815 case AARCH64_MOD_MSL:
1816 /* Only 8 and 16 are valid shift amount. */
1817 if (opnd->shifter.amount != 8 && opnd->shifter.amount != 16)
1818 {
1819 set_other_error (mismatch_detail, idx,
1820 _("shift amount expected to be 0 or 16"));
1821 return 0;
1822 }
1823 break;
1824 default:
1825 if (opnd->shifter.kind != AARCH64_MOD_NONE)
1826 {
1827 set_other_error (mismatch_detail, idx,
1828 _("invalid shift operator"));
1829 return 0;
1830 }
1831 break;
1832 }
1833 break;
1834
1835 case AARCH64_OPND_FPIMM:
1836 case AARCH64_OPND_SIMD_FPIMM:
1837 if (opnd->imm.is_fp == 0)
1838 {
1839 set_other_error (mismatch_detail, idx,
1840 _("floating-point immediate expected"));
1841 return 0;
1842 }
1843 /* The value is expected to be an 8-bit floating-point constant with
1844 sign, 3-bit exponent and normalized 4 bits of precision, encoded
1845 in "a:b:c:d:e:f:g:h" or FLD_imm8 (depending on the type of the
1846 instruction). */
1847 if (!value_in_range_p (opnd->imm.value, 0, 255))
1848 {
1849 set_other_error (mismatch_detail, idx,
1850 _("immediate out of range"));
1851 return 0;
1852 }
1853 if (opnd->shifter.kind != AARCH64_MOD_NONE)
1854 {
1855 set_other_error (mismatch_detail, idx,
1856 _("invalid shift operator"));
1857 return 0;
1858 }
1859 break;
1860
1861 default:
1862 break;
1863 }
1864 break;
1865
1866 case AARCH64_OPND_CLASS_CP_REG:
1867 /* Cn or Cm: 4-bit opcode field named for historical reasons.
1868 valid range: C0 - C15. */
1869 if (opnd->reg.regno > 15)
1870 {
1871 set_regno_out_of_range_error (mismatch_detail, idx, 0, 15);
1872 return 0;
1873 }
1874 break;
1875
1876 case AARCH64_OPND_CLASS_SYSTEM:
1877 switch (type)
1878 {
1879 case AARCH64_OPND_PSTATEFIELD:
1880 assert (idx == 0 && opnds[1].type == AARCH64_OPND_UIMM4);
0bff6e2d
MW
1881 /* MSR UAO, #uimm4
1882 MSR PAN, #uimm4
c2825638 1883 The immediate must be #0 or #1. */
0bff6e2d
MW
1884 if ((opnd->pstatefield == 0x03 /* UAO. */
1885 || opnd->pstatefield == 0x04) /* PAN. */
c2825638
MW
1886 && opnds[1].imm.value > 1)
1887 {
1888 set_imm_out_of_range_error (mismatch_detail, idx, 0, 1);
1889 return 0;
1890 }
a06ea964
NC
1891 /* MSR SPSel, #uimm4
1892 Uses uimm4 as a control value to select the stack pointer: if
1893 bit 0 is set it selects the current exception level's stack
1894 pointer, if bit 0 is clear it selects shared EL0 stack pointer.
1895 Bits 1 to 3 of uimm4 are reserved and should be zero. */
1896 if (opnd->pstatefield == 0x05 /* spsel */ && opnds[1].imm.value > 1)
1897 {
1898 set_imm_out_of_range_error (mismatch_detail, idx, 0, 1);
1899 return 0;
1900 }
1901 break;
1902 default:
1903 break;
1904 }
1905 break;
1906
1907 case AARCH64_OPND_CLASS_SIMD_ELEMENT:
1908 /* Get the upper bound for the element index. */
1909 num = 16 / aarch64_get_qualifier_esize (qualifier) - 1;
1910 /* Index out-of-range. */
1911 if (!value_in_range_p (opnd->reglane.index, 0, num))
1912 {
1913 set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, num);
1914 return 0;
1915 }
1916 /* SMLAL<Q> <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>].
1917 <Vm> Is the vector register (V0-V31) or (V0-V15), whose
1918 number is encoded in "size:M:Rm":
1919 size <Vm>
1920 00 RESERVED
1921 01 0:Rm
1922 10 M:Rm
1923 11 RESERVED */
1924 if (type == AARCH64_OPND_Em && qualifier == AARCH64_OPND_QLF_S_H
1925 && !value_in_range_p (opnd->reglane.regno, 0, 15))
1926 {
1927 set_regno_out_of_range_error (mismatch_detail, idx, 0, 15);
1928 return 0;
1929 }
1930 break;
1931
1932 case AARCH64_OPND_CLASS_MODIFIED_REG:
1933 assert (idx == 1 || idx == 2);
1934 switch (type)
1935 {
1936 case AARCH64_OPND_Rm_EXT:
1937 if (aarch64_extend_operator_p (opnd->shifter.kind) == FALSE
1938 && opnd->shifter.kind != AARCH64_MOD_LSL)
1939 {
1940 set_other_error (mismatch_detail, idx,
1941 _("extend operator expected"));
1942 return 0;
1943 }
1944 /* It is not optional unless at least one of "Rd" or "Rn" is '11111'
1945 (i.e. SP), in which case it defaults to LSL. The LSL alias is
1946 only valid when "Rd" or "Rn" is '11111', and is preferred in that
1947 case. */
1948 if (!aarch64_stack_pointer_p (opnds + 0)
1949 && (idx != 2 || !aarch64_stack_pointer_p (opnds + 1)))
1950 {
1951 if (!opnd->shifter.operator_present)
1952 {
1953 set_other_error (mismatch_detail, idx,
1954 _("missing extend operator"));
1955 return 0;
1956 }
1957 else if (opnd->shifter.kind == AARCH64_MOD_LSL)
1958 {
1959 set_other_error (mismatch_detail, idx,
1960 _("'LSL' operator not allowed"));
1961 return 0;
1962 }
1963 }
1964 assert (opnd->shifter.operator_present /* Default to LSL. */
1965 || opnd->shifter.kind == AARCH64_MOD_LSL);
1966 if (!value_in_range_p (opnd->shifter.amount, 0, 4))
1967 {
1968 set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, 4);
1969 return 0;
1970 }
1971 /* In the 64-bit form, the final register operand is written as Wm
1972 for all but the (possibly omitted) UXTX/LSL and SXTX
1973 operators.
1974 N.B. GAS allows X register to be used with any operator as a
1975 programming convenience. */
1976 if (qualifier == AARCH64_OPND_QLF_X
1977 && opnd->shifter.kind != AARCH64_MOD_LSL
1978 && opnd->shifter.kind != AARCH64_MOD_UXTX
1979 && opnd->shifter.kind != AARCH64_MOD_SXTX)
1980 {
1981 set_other_error (mismatch_detail, idx, _("W register expected"));
1982 return 0;
1983 }
1984 break;
1985
1986 case AARCH64_OPND_Rm_SFT:
1987 /* ROR is not available to the shifted register operand in
1988 arithmetic instructions. */
1989 if (aarch64_shift_operator_p (opnd->shifter.kind) == FALSE)
1990 {
1991 set_other_error (mismatch_detail, idx,
1992 _("shift operator expected"));
1993 return 0;
1994 }
1995 if (opnd->shifter.kind == AARCH64_MOD_ROR
1996 && opcode->iclass != log_shift)
1997 {
1998 set_other_error (mismatch_detail, idx,
1999 _("'ROR' operator not allowed"));
2000 return 0;
2001 }
2002 num = qualifier == AARCH64_OPND_QLF_W ? 31 : 63;
2003 if (!value_in_range_p (opnd->shifter.amount, 0, num))
2004 {
2005 set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, num);
2006 return 0;
2007 }
2008 break;
2009
2010 default:
2011 break;
2012 }
2013 break;
2014
2015 default:
2016 break;
2017 }
2018
2019 return 1;
2020}
2021
2022/* Main entrypoint for the operand constraint checking.
2023
2024 Return 1 if operands of *INST meet the constraint applied by the operand
2025 codes and operand qualifiers; otherwise return 0 and if MISMATCH_DETAIL is
2026 not NULL, return the detail of the error in *MISMATCH_DETAIL. N.B. when
2027 adding more constraint checking, make sure MISMATCH_DETAIL->KIND is set
2028 with a proper error kind rather than AARCH64_OPDE_NIL (GAS asserts non-NIL
2029 error kind when it is notified that an instruction does not pass the check).
2030
2031 Un-determined operand qualifiers may get established during the process. */
2032
2033int
2034aarch64_match_operands_constraint (aarch64_inst *inst,
2035 aarch64_operand_error *mismatch_detail)
2036{
2037 int i;
2038
2039 DEBUG_TRACE ("enter");
2040
2041 /* Match operands' qualifier.
2042 *INST has already had qualifier establish for some, if not all, of
2043 its operands; we need to find out whether these established
2044 qualifiers match one of the qualifier sequence in
2045 INST->OPCODE->QUALIFIERS_LIST. If yes, we will assign each operand
2046 with the corresponding qualifier in such a sequence.
2047 Only basic operand constraint checking is done here; the more thorough
2048 constraint checking will carried out by operand_general_constraint_met_p,
2049 which has be to called after this in order to get all of the operands'
2050 qualifiers established. */
2051 if (match_operands_qualifier (inst, TRUE /* update_p */) == 0)
2052 {
2053 DEBUG_TRACE ("FAIL on operand qualifier matching");
2054 if (mismatch_detail)
2055 {
2056 /* Return an error type to indicate that it is the qualifier
2057 matching failure; we don't care about which operand as there
2058 are enough information in the opcode table to reproduce it. */
2059 mismatch_detail->kind = AARCH64_OPDE_INVALID_VARIANT;
2060 mismatch_detail->index = -1;
2061 mismatch_detail->error = NULL;
2062 }
2063 return 0;
2064 }
2065
2066 /* Match operands' constraint. */
2067 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2068 {
2069 enum aarch64_opnd type = inst->opcode->operands[i];
2070 if (type == AARCH64_OPND_NIL)
2071 break;
2072 if (inst->operands[i].skip)
2073 {
2074 DEBUG_TRACE ("skip the incomplete operand %d", i);
2075 continue;
2076 }
2077 if (operand_general_constraint_met_p (inst->operands, i, type,
2078 inst->opcode, mismatch_detail) == 0)
2079 {
2080 DEBUG_TRACE ("FAIL on operand %d", i);
2081 return 0;
2082 }
2083 }
2084
2085 DEBUG_TRACE ("PASS");
2086
2087 return 1;
2088}
2089
2090/* Replace INST->OPCODE with OPCODE and return the replaced OPCODE.
2091 Also updates the TYPE of each INST->OPERANDS with the corresponding
2092 value of OPCODE->OPERANDS.
2093
2094 Note that some operand qualifiers may need to be manually cleared by
2095 the caller before it further calls the aarch64_opcode_encode; by
2096 doing this, it helps the qualifier matching facilities work
2097 properly. */
2098
2099const aarch64_opcode*
2100aarch64_replace_opcode (aarch64_inst *inst, const aarch64_opcode *opcode)
2101{
2102 int i;
2103 const aarch64_opcode *old = inst->opcode;
2104
2105 inst->opcode = opcode;
2106
2107 /* Update the operand types. */
2108 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2109 {
2110 inst->operands[i].type = opcode->operands[i];
2111 if (opcode->operands[i] == AARCH64_OPND_NIL)
2112 break;
2113 }
2114
2115 DEBUG_TRACE ("replace %s with %s", old->name, opcode->name);
2116
2117 return old;
2118}
2119
2120int
2121aarch64_operand_index (const enum aarch64_opnd *operands, enum aarch64_opnd operand)
2122{
2123 int i;
2124 for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
2125 if (operands[i] == operand)
2126 return i;
2127 else if (operands[i] == AARCH64_OPND_NIL)
2128 break;
2129 return -1;
2130}
2131\f
2132/* [0][0] 32-bit integer regs with sp Wn
2133 [0][1] 64-bit integer regs with sp Xn sf=1
2134 [1][0] 32-bit integer regs with #0 Wn
2135 [1][1] 64-bit integer regs with #0 Xn sf=1 */
2136static const char *int_reg[2][2][32] = {
2137#define R32 "w"
2138#define R64 "x"
2139 { { R32 "0", R32 "1", R32 "2", R32 "3", R32 "4", R32 "5", R32 "6", R32 "7",
2140 R32 "8", R32 "9", R32 "10", R32 "11", R32 "12", R32 "13", R32 "14", R32 "15",
2141 R32 "16", R32 "17", R32 "18", R32 "19", R32 "20", R32 "21", R32 "22", R32 "23",
2142 R32 "24", R32 "25", R32 "26", R32 "27", R32 "28", R32 "29", R32 "30", "wsp" },
2143 { R64 "0", R64 "1", R64 "2", R64 "3", R64 "4", R64 "5", R64 "6", R64 "7",
2144 R64 "8", R64 "9", R64 "10", R64 "11", R64 "12", R64 "13", R64 "14", R64 "15",
2145 R64 "16", R64 "17", R64 "18", R64 "19", R64 "20", R64 "21", R64 "22", R64 "23",
2146 R64 "24", R64 "25", R64 "26", R64 "27", R64 "28", R64 "29", R64 "30", "sp" } },
2147 { { R32 "0", R32 "1", R32 "2", R32 "3", R32 "4", R32 "5", R32 "6", R32 "7",
2148 R32 "8", R32 "9", R32 "10", R32 "11", R32 "12", R32 "13", R32 "14", R32 "15",
2149 R32 "16", R32 "17", R32 "18", R32 "19", R32 "20", R32 "21", R32 "22", R32 "23",
2150 R32 "24", R32 "25", R32 "26", R32 "27", R32 "28", R32 "29", R32 "30", R32 "zr" },
2151 { R64 "0", R64 "1", R64 "2", R64 "3", R64 "4", R64 "5", R64 "6", R64 "7",
2152 R64 "8", R64 "9", R64 "10", R64 "11", R64 "12", R64 "13", R64 "14", R64 "15",
2153 R64 "16", R64 "17", R64 "18", R64 "19", R64 "20", R64 "21", R64 "22", R64 "23",
2154 R64 "24", R64 "25", R64 "26", R64 "27", R64 "28", R64 "29", R64 "30", R64 "zr" } }
2155#undef R64
2156#undef R32
2157};
2158
2159/* Return the integer register name.
2160 if SP_REG_P is not 0, R31 is an SP reg, other R31 is the zero reg. */
2161
2162static inline const char *
2163get_int_reg_name (int regno, aarch64_opnd_qualifier_t qualifier, int sp_reg_p)
2164{
2165 const int has_zr = sp_reg_p ? 0 : 1;
2166 const int is_64 = aarch64_get_qualifier_esize (qualifier) == 4 ? 0 : 1;
2167 return int_reg[has_zr][is_64][regno];
2168}
2169
2170/* Like get_int_reg_name, but IS_64 is always 1. */
2171
2172static inline const char *
2173get_64bit_int_reg_name (int regno, int sp_reg_p)
2174{
2175 const int has_zr = sp_reg_p ? 0 : 1;
2176 return int_reg[has_zr][1][regno];
2177}
2178
2179/* Types for expanding an encoded 8-bit value to a floating-point value. */
2180
2181typedef union
2182{
2183 uint64_t i;
2184 double d;
2185} double_conv_t;
2186
2187typedef union
2188{
2189 uint32_t i;
2190 float f;
2191} single_conv_t;
2192
cf86120b
MW
2193typedef union
2194{
2195 uint32_t i;
2196 float f;
2197} half_conv_t;
2198
a06ea964
NC
2199/* IMM8 is an 8-bit floating-point constant with sign, 3-bit exponent and
2200 normalized 4 bits of precision, encoded in "a:b:c:d:e:f:g:h" or FLD_imm8
2201 (depending on the type of the instruction). IMM8 will be expanded to a
cf86120b
MW
2202 single-precision floating-point value (SIZE == 4) or a double-precision
2203 floating-point value (SIZE == 8). A half-precision floating-point value
2204 (SIZE == 2) is expanded to a single-precision floating-point value. The
2205 expanded value is returned. */
a06ea964
NC
2206
2207static uint64_t
cf86120b 2208expand_fp_imm (int size, uint32_t imm8)
a06ea964
NC
2209{
2210 uint64_t imm;
2211 uint32_t imm8_7, imm8_6_0, imm8_6, imm8_6_repl4;
2212
2213 imm8_7 = (imm8 >> 7) & 0x01; /* imm8<7> */
2214 imm8_6_0 = imm8 & 0x7f; /* imm8<6:0> */
2215 imm8_6 = imm8_6_0 >> 6; /* imm8<6> */
2216 imm8_6_repl4 = (imm8_6 << 3) | (imm8_6 << 2)
2217 | (imm8_6 << 1) | imm8_6; /* Replicate(imm8<6>,4) */
cf86120b 2218 if (size == 8)
a06ea964
NC
2219 {
2220 imm = (imm8_7 << (63-32)) /* imm8<7> */
2221 | ((imm8_6 ^ 1) << (62-32)) /* NOT(imm8<6) */
2222 | (imm8_6_repl4 << (58-32)) | (imm8_6 << (57-32))
2223 | (imm8_6 << (56-32)) | (imm8_6 << (55-32)) /* Replicate(imm8<6>,7) */
2224 | (imm8_6_0 << (48-32)); /* imm8<6>:imm8<5:0> */
2225 imm <<= 32;
2226 }
cf86120b 2227 else if (size == 4 || size == 2)
a06ea964
NC
2228 {
2229 imm = (imm8_7 << 31) /* imm8<7> */
2230 | ((imm8_6 ^ 1) << 30) /* NOT(imm8<6>) */
2231 | (imm8_6_repl4 << 26) /* Replicate(imm8<6>,4) */
2232 | (imm8_6_0 << 19); /* imm8<6>:imm8<5:0> */
2233 }
cf86120b
MW
2234 else
2235 {
2236 /* An unsupported size. */
2237 assert (0);
2238 }
a06ea964
NC
2239
2240 return imm;
2241}
2242
2243/* Produce the string representation of the register list operand *OPND
2244 in the buffer pointed by BUF of size SIZE. */
2245static void
2246print_register_list (char *buf, size_t size, const aarch64_opnd_info *opnd)
2247{
2248 const int num_regs = opnd->reglist.num_regs;
2249 const int first_reg = opnd->reglist.first_regno;
2250 const int last_reg = (first_reg + num_regs - 1) & 0x1f;
2251 const char *qlf_name = aarch64_get_qualifier_name (opnd->qualifier);
2252 char tb[8]; /* Temporary buffer. */
2253
2254 assert (opnd->type != AARCH64_OPND_LEt || opnd->reglist.has_index);
2255 assert (num_regs >= 1 && num_regs <= 4);
2256
2257 /* Prepare the index if any. */
2258 if (opnd->reglist.has_index)
2259 snprintf (tb, 8, "[%d]", opnd->reglist.index);
2260 else
2261 tb[0] = '\0';
2262
2263 /* The hyphenated form is preferred for disassembly if there are
2264 more than two registers in the list, and the register numbers
2265 are monotonically increasing in increments of one. */
2266 if (num_regs > 2 && last_reg > first_reg)
2267 snprintf (buf, size, "{v%d.%s-v%d.%s}%s", first_reg, qlf_name,
2268 last_reg, qlf_name, tb);
2269 else
2270 {
2271 const int reg0 = first_reg;
2272 const int reg1 = (first_reg + 1) & 0x1f;
2273 const int reg2 = (first_reg + 2) & 0x1f;
2274 const int reg3 = (first_reg + 3) & 0x1f;
2275
2276 switch (num_regs)
2277 {
2278 case 1:
2279 snprintf (buf, size, "{v%d.%s}%s", reg0, qlf_name, tb);
2280 break;
2281 case 2:
2282 snprintf (buf, size, "{v%d.%s, v%d.%s}%s", reg0, qlf_name,
2283 reg1, qlf_name, tb);
2284 break;
2285 case 3:
2286 snprintf (buf, size, "{v%d.%s, v%d.%s, v%d.%s}%s", reg0, qlf_name,
2287 reg1, qlf_name, reg2, qlf_name, tb);
2288 break;
2289 case 4:
2290 snprintf (buf, size, "{v%d.%s, v%d.%s, v%d.%s, v%d.%s}%s",
2291 reg0, qlf_name, reg1, qlf_name, reg2, qlf_name,
2292 reg3, qlf_name, tb);
2293 break;
2294 }
2295 }
2296}
2297
2298/* Produce the string representation of the register offset address operand
2299 *OPND in the buffer pointed by BUF of size SIZE. */
2300static void
2301print_register_offset_address (char *buf, size_t size,
2302 const aarch64_opnd_info *opnd)
2303{
0d2f91fe 2304 char tb[16]; /* Temporary buffer. */
a06ea964
NC
2305 bfd_boolean lsl_p = FALSE; /* Is LSL shift operator? */
2306 bfd_boolean wm_p = FALSE; /* Should Rm be Wm? */
2307 bfd_boolean print_extend_p = TRUE;
2308 bfd_boolean print_amount_p = TRUE;
2309 const char *shift_name = aarch64_operand_modifiers[opnd->shifter.kind].name;
2310
2311 switch (opnd->shifter.kind)
2312 {
2313 case AARCH64_MOD_UXTW: wm_p = TRUE; break;
2314 case AARCH64_MOD_LSL : lsl_p = TRUE; break;
2315 case AARCH64_MOD_SXTW: wm_p = TRUE; break;
2316 case AARCH64_MOD_SXTX: break;
2317 default: assert (0);
2318 }
2319
2320 if (!opnd->shifter.amount && (opnd->qualifier != AARCH64_OPND_QLF_S_B
2321 || !opnd->shifter.amount_present))
2322 {
2323 /* Not print the shift/extend amount when the amount is zero and
2324 when it is not the special case of 8-bit load/store instruction. */
2325 print_amount_p = FALSE;
2326 /* Likewise, no need to print the shift operator LSL in such a
2327 situation. */
2328 if (lsl_p)
2329 print_extend_p = FALSE;
2330 }
2331
2332 /* Prepare for the extend/shift. */
2333 if (print_extend_p)
2334 {
2335 if (print_amount_p)
0d2f91fe 2336 snprintf (tb, sizeof (tb), ",%s #%d", shift_name, opnd->shifter.amount);
a06ea964 2337 else
0d2f91fe 2338 snprintf (tb, sizeof (tb), ",%s", shift_name);
a06ea964
NC
2339 }
2340 else
2341 tb[0] = '\0';
2342
a58549dd 2343 snprintf (buf, size, "[%s,%s%s]",
a06ea964 2344 get_64bit_int_reg_name (opnd->addr.base_regno, 1),
a58549dd
YZ
2345 get_int_reg_name (opnd->addr.offset.regno,
2346 wm_p ? AARCH64_OPND_QLF_W : AARCH64_OPND_QLF_X,
2347 0 /* sp_reg_p */),
2348 tb);
a06ea964
NC
2349}
2350
2351/* Generate the string representation of the operand OPNDS[IDX] for OPCODE
2352 in *BUF. The caller should pass in the maximum size of *BUF in SIZE.
2353 PC, PCREL_P and ADDRESS are used to pass in and return information about
2354 the PC-relative address calculation, where the PC value is passed in
2355 PC. If the operand is pc-relative related, *PCREL_P (if PCREL_P non-NULL)
2356 will return 1 and *ADDRESS (if ADDRESS non-NULL) will return the
2357 calculated address; otherwise, *PCREL_P (if PCREL_P non-NULL) returns 0.
2358
2359 The function serves both the disassembler and the assembler diagnostics
2360 issuer, which is the reason why it lives in this file. */
2361
2362void
2363aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
2364 const aarch64_opcode *opcode,
2365 const aarch64_opnd_info *opnds, int idx, int *pcrel_p,
2366 bfd_vma *address)
2367{
2368 int i;
2369 const char *name = NULL;
2370 const aarch64_opnd_info *opnd = opnds + idx;
2371 enum aarch64_modifier_kind kind;
2372 uint64_t addr;
2373
2374 buf[0] = '\0';
2375 if (pcrel_p)
2376 *pcrel_p = 0;
2377
2378 switch (opnd->type)
2379 {
2380 case AARCH64_OPND_Rd:
2381 case AARCH64_OPND_Rn:
2382 case AARCH64_OPND_Rm:
2383 case AARCH64_OPND_Rt:
2384 case AARCH64_OPND_Rt2:
2385 case AARCH64_OPND_Rs:
2386 case AARCH64_OPND_Ra:
2387 case AARCH64_OPND_Rt_SYS:
ee804238 2388 case AARCH64_OPND_PAIRREG:
a06ea964
NC
2389 /* The optional-ness of <Xt> in e.g. IC <ic_op>{, <Xt>} is determined by
2390 the <ic_op>, therefore we we use opnd->present to override the
2391 generic optional-ness information. */
2392 if (opnd->type == AARCH64_OPND_Rt_SYS && !opnd->present)
2393 break;
2394 /* Omit the operand, e.g. RET. */
2395 if (optional_operand_p (opcode, idx)
2396 && opnd->reg.regno == get_optional_operand_default_value (opcode))
2397 break;
2398 assert (opnd->qualifier == AARCH64_OPND_QLF_W
2399 || opnd->qualifier == AARCH64_OPND_QLF_X);
2400 snprintf (buf, size, "%s",
2401 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
2402 break;
2403
2404 case AARCH64_OPND_Rd_SP:
2405 case AARCH64_OPND_Rn_SP:
2406 assert (opnd->qualifier == AARCH64_OPND_QLF_W
2407 || opnd->qualifier == AARCH64_OPND_QLF_WSP
2408 || opnd->qualifier == AARCH64_OPND_QLF_X
2409 || opnd->qualifier == AARCH64_OPND_QLF_SP);
2410 snprintf (buf, size, "%s",
2411 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 1));
2412 break;
2413
2414 case AARCH64_OPND_Rm_EXT:
2415 kind = opnd->shifter.kind;
2416 assert (idx == 1 || idx == 2);
2417 if ((aarch64_stack_pointer_p (opnds)
2418 || (idx == 2 && aarch64_stack_pointer_p (opnds + 1)))
2419 && ((opnd->qualifier == AARCH64_OPND_QLF_W
2420 && opnds[0].qualifier == AARCH64_OPND_QLF_W
2421 && kind == AARCH64_MOD_UXTW)
2422 || (opnd->qualifier == AARCH64_OPND_QLF_X
2423 && kind == AARCH64_MOD_UXTX)))
2424 {
2425 /* 'LSL' is the preferred form in this case. */
2426 kind = AARCH64_MOD_LSL;
2427 if (opnd->shifter.amount == 0)
2428 {
2429 /* Shifter omitted. */
2430 snprintf (buf, size, "%s",
2431 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
2432 break;
2433 }
2434 }
2435 if (opnd->shifter.amount)
2436 snprintf (buf, size, "%s, %s #%d",
2437 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
2438 aarch64_operand_modifiers[kind].name,
2439 opnd->shifter.amount);
2440 else
2441 snprintf (buf, size, "%s, %s",
2442 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
2443 aarch64_operand_modifiers[kind].name);
2444 break;
2445
2446 case AARCH64_OPND_Rm_SFT:
2447 assert (opnd->qualifier == AARCH64_OPND_QLF_W
2448 || opnd->qualifier == AARCH64_OPND_QLF_X);
2449 if (opnd->shifter.amount == 0 && opnd->shifter.kind == AARCH64_MOD_LSL)
2450 snprintf (buf, size, "%s",
2451 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
2452 else
2453 snprintf (buf, size, "%s, %s #%d",
2454 get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
2455 aarch64_operand_modifiers[opnd->shifter.kind].name,
2456 opnd->shifter.amount);
2457 break;
2458
2459 case AARCH64_OPND_Fd:
2460 case AARCH64_OPND_Fn:
2461 case AARCH64_OPND_Fm:
2462 case AARCH64_OPND_Fa:
2463 case AARCH64_OPND_Ft:
2464 case AARCH64_OPND_Ft2:
2465 case AARCH64_OPND_Sd:
2466 case AARCH64_OPND_Sn:
2467 case AARCH64_OPND_Sm:
2468 snprintf (buf, size, "%s%d", aarch64_get_qualifier_name (opnd->qualifier),
2469 opnd->reg.regno);
2470 break;
2471
2472 case AARCH64_OPND_Vd:
2473 case AARCH64_OPND_Vn:
2474 case AARCH64_OPND_Vm:
2475 snprintf (buf, size, "v%d.%s", opnd->reg.regno,
2476 aarch64_get_qualifier_name (opnd->qualifier));
2477 break;
2478
2479 case AARCH64_OPND_Ed:
2480 case AARCH64_OPND_En:
2481 case AARCH64_OPND_Em:
2482 snprintf (buf, size, "v%d.%s[%d]", opnd->reglane.regno,
2483 aarch64_get_qualifier_name (opnd->qualifier),
2484 opnd->reglane.index);
2485 break;
2486
2487 case AARCH64_OPND_VdD1:
2488 case AARCH64_OPND_VnD1:
2489 snprintf (buf, size, "v%d.d[1]", opnd->reg.regno);
2490 break;
2491
2492 case AARCH64_OPND_LVn:
2493 case AARCH64_OPND_LVt:
2494 case AARCH64_OPND_LVt_AL:
2495 case AARCH64_OPND_LEt:
2496 print_register_list (buf, size, opnd);
2497 break;
2498
2499 case AARCH64_OPND_Cn:
2500 case AARCH64_OPND_Cm:
2501 snprintf (buf, size, "C%d", opnd->reg.regno);
2502 break;
2503
2504 case AARCH64_OPND_IDX:
2505 case AARCH64_OPND_IMM:
2506 case AARCH64_OPND_WIDTH:
2507 case AARCH64_OPND_UIMM3_OP1:
2508 case AARCH64_OPND_UIMM3_OP2:
2509 case AARCH64_OPND_BIT_NUM:
2510 case AARCH64_OPND_IMM_VLSL:
2511 case AARCH64_OPND_IMM_VLSR:
2512 case AARCH64_OPND_SHLL_IMM:
2513 case AARCH64_OPND_IMM0:
2514 case AARCH64_OPND_IMMR:
2515 case AARCH64_OPND_IMMS:
2516 case AARCH64_OPND_FBITS:
a06ea964
NC
2517 snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
2518 break;
2519
fb098a1e
YZ
2520 case AARCH64_OPND_IMM_MOV:
2521 switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
2522 {
2523 case 4: /* e.g. MOV Wd, #<imm32>. */
2524 {
2525 int imm32 = opnd->imm.value;
2526 snprintf (buf, size, "#0x%-20x\t// #%d", imm32, imm32);
2527 }
2528 break;
2529 case 8: /* e.g. MOV Xd, #<imm64>. */
2530 snprintf (buf, size, "#0x%-20" PRIx64 "\t// #%" PRIi64,
2531 opnd->imm.value, opnd->imm.value);
2532 break;
2533 default: assert (0);
2534 }
2535 break;
2536
a06ea964
NC
2537 case AARCH64_OPND_FPIMM0:
2538 snprintf (buf, size, "#0.0");
2539 break;
2540
2541 case AARCH64_OPND_LIMM:
2542 case AARCH64_OPND_AIMM:
2543 case AARCH64_OPND_HALF:
2544 if (opnd->shifter.amount)
2545 snprintf (buf, size, "#0x%" PRIx64 ", lsl #%d", opnd->imm.value,
2546 opnd->shifter.amount);
2547 else
2548 snprintf (buf, size, "#0x%" PRIx64, opnd->imm.value);
2549 break;
2550
2551 case AARCH64_OPND_SIMD_IMM:
2552 case AARCH64_OPND_SIMD_IMM_SFT:
2553 if ((! opnd->shifter.amount && opnd->shifter.kind == AARCH64_MOD_LSL)
2554 || opnd->shifter.kind == AARCH64_MOD_NONE)
2555 snprintf (buf, size, "#0x%" PRIx64, opnd->imm.value);
2556 else
2557 snprintf (buf, size, "#0x%" PRIx64 ", %s #%d", opnd->imm.value,
2558 aarch64_operand_modifiers[opnd->shifter.kind].name,
2559 opnd->shifter.amount);
2560 break;
2561
2562 case AARCH64_OPND_FPIMM:
2563 case AARCH64_OPND_SIMD_FPIMM:
2564 switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
2565 {
cf86120b
MW
2566 case 2: /* e.g. FMOV <Hd>, #<imm>. */
2567 {
2568 half_conv_t c;
2569 c.i = expand_fp_imm (2, opnd->imm.value);
2570 snprintf (buf, size, "#%.18e", c.f);
2571 }
2572 break;
a06ea964
NC
2573 case 4: /* e.g. FMOV <Vd>.4S, #<imm>. */
2574 {
2575 single_conv_t c;
cf86120b 2576 c.i = expand_fp_imm (4, opnd->imm.value);
a06ea964
NC
2577 snprintf (buf, size, "#%.18e", c.f);
2578 }
2579 break;
2580 case 8: /* e.g. FMOV <Sd>, #<imm>. */
2581 {
2582 double_conv_t c;
cf86120b 2583 c.i = expand_fp_imm (8, opnd->imm.value);
a06ea964
NC
2584 snprintf (buf, size, "#%.18e", c.d);
2585 }
2586 break;
2587 default: assert (0);
2588 }
2589 break;
2590
2591 case AARCH64_OPND_CCMP_IMM:
2592 case AARCH64_OPND_NZCV:
2593 case AARCH64_OPND_EXCEPTION:
2594 case AARCH64_OPND_UIMM4:
2595 case AARCH64_OPND_UIMM7:
2596 if (optional_operand_p (opcode, idx) == TRUE
2597 && (opnd->imm.value ==
2598 (int64_t) get_optional_operand_default_value (opcode)))
2599 /* Omit the operand, e.g. DCPS1. */
2600 break;
2601 snprintf (buf, size, "#0x%x", (unsigned int)opnd->imm.value);
2602 break;
2603
2604 case AARCH64_OPND_COND:
68a64283 2605 case AARCH64_OPND_COND1:
a06ea964
NC
2606 snprintf (buf, size, "%s", opnd->cond->names[0]);
2607 break;
2608
2609 case AARCH64_OPND_ADDR_ADRP:
2610 addr = ((pc + AARCH64_PCREL_OFFSET) & ~(uint64_t)0xfff)
2611 + opnd->imm.value;
2612 if (pcrel_p)
2613 *pcrel_p = 1;
2614 if (address)
2615 *address = addr;
2616 /* This is not necessary during the disassembling, as print_address_func
2617 in the disassemble_info will take care of the printing. But some
2618 other callers may be still interested in getting the string in *STR,
2619 so here we do snprintf regardless. */
2620 snprintf (buf, size, "#0x%" PRIx64, addr);
2621 break;
2622
2623 case AARCH64_OPND_ADDR_PCREL14:
2624 case AARCH64_OPND_ADDR_PCREL19:
2625 case AARCH64_OPND_ADDR_PCREL21:
2626 case AARCH64_OPND_ADDR_PCREL26:
2627 addr = pc + AARCH64_PCREL_OFFSET + opnd->imm.value;
2628 if (pcrel_p)
2629 *pcrel_p = 1;
2630 if (address)
2631 *address = addr;
2632 /* This is not necessary during the disassembling, as print_address_func
2633 in the disassemble_info will take care of the printing. But some
2634 other callers may be still interested in getting the string in *STR,
2635 so here we do snprintf regardless. */
2636 snprintf (buf, size, "#0x%" PRIx64, addr);
2637 break;
2638
2639 case AARCH64_OPND_ADDR_SIMPLE:
2640 case AARCH64_OPND_SIMD_ADDR_SIMPLE:
2641 case AARCH64_OPND_SIMD_ADDR_POST:
2642 name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
2643 if (opnd->type == AARCH64_OPND_SIMD_ADDR_POST)
2644 {
2645 if (opnd->addr.offset.is_reg)
2646 snprintf (buf, size, "[%s], x%d", name, opnd->addr.offset.regno);
2647 else
2648 snprintf (buf, size, "[%s], #%d", name, opnd->addr.offset.imm);
2649 }
2650 else
2651 snprintf (buf, size, "[%s]", name);
2652 break;
2653
2654 case AARCH64_OPND_ADDR_REGOFF:
2655 print_register_offset_address (buf, size, opnd);
2656 break;
2657
2658 case AARCH64_OPND_ADDR_SIMM7:
2659 case AARCH64_OPND_ADDR_SIMM9:
2660 case AARCH64_OPND_ADDR_SIMM9_2:
2661 name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
2662 if (opnd->addr.writeback)
2663 {
2664 if (opnd->addr.preind)
2665 snprintf (buf, size, "[%s,#%d]!", name, opnd->addr.offset.imm);
2666 else
2667 snprintf (buf, size, "[%s],#%d", name, opnd->addr.offset.imm);
2668 }
2669 else
2670 {
2671 if (opnd->addr.offset.imm)
2672 snprintf (buf, size, "[%s,#%d]", name, opnd->addr.offset.imm);
2673 else
2674 snprintf (buf, size, "[%s]", name);
2675 }
2676 break;
2677
2678 case AARCH64_OPND_ADDR_UIMM12:
2679 name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
2680 if (opnd->addr.offset.imm)
2681 snprintf (buf, size, "[%s,#%d]", name, opnd->addr.offset.imm);
2682 else
2683 snprintf (buf, size, "[%s]", name);
2684 break;
2685
2686 case AARCH64_OPND_SYSREG:
2687 for (i = 0; aarch64_sys_regs[i].name; ++i)
49eec193
YZ
2688 if (aarch64_sys_regs[i].value == opnd->sysreg
2689 && ! aarch64_sys_reg_deprecated_p (&aarch64_sys_regs[i]))
a06ea964
NC
2690 break;
2691 if (aarch64_sys_regs[i].name)
2692 snprintf (buf, size, "%s", aarch64_sys_regs[i].name);
2693 else
2694 {
2695 /* Implementation defined system register. */
2696 unsigned int value = opnd->sysreg;
2697 snprintf (buf, size, "s%u_%u_c%u_c%u_%u", (value >> 14) & 0x3,
2698 (value >> 11) & 0x7, (value >> 7) & 0xf, (value >> 3) & 0xf,
2699 value & 0x7);
2700 }
2701 break;
2702
2703 case AARCH64_OPND_PSTATEFIELD:
2704 for (i = 0; aarch64_pstatefields[i].name; ++i)
2705 if (aarch64_pstatefields[i].value == opnd->pstatefield)
2706 break;
2707 assert (aarch64_pstatefields[i].name);
2708 snprintf (buf, size, "%s", aarch64_pstatefields[i].name);
2709 break;
2710
2711 case AARCH64_OPND_SYSREG_AT:
2712 case AARCH64_OPND_SYSREG_DC:
2713 case AARCH64_OPND_SYSREG_IC:
2714 case AARCH64_OPND_SYSREG_TLBI:
875880c6 2715 snprintf (buf, size, "%s", opnd->sysins_op->name);
a06ea964
NC
2716 break;
2717
2718 case AARCH64_OPND_BARRIER:
2719 snprintf (buf, size, "%s", opnd->barrier->name);
2720 break;
2721
2722 case AARCH64_OPND_BARRIER_ISB:
2723 /* Operand can be omitted, e.g. in DCPS1. */
2724 if (! optional_operand_p (opcode, idx)
2725 || (opnd->barrier->value
2726 != get_optional_operand_default_value (opcode)))
2727 snprintf (buf, size, "#0x%x", opnd->barrier->value);
2728 break;
2729
2730 case AARCH64_OPND_PRFOP:
a1ccaec9
YZ
2731 if (opnd->prfop->name != NULL)
2732 snprintf (buf, size, "%s", opnd->prfop->name);
2733 else
2734 snprintf (buf, size, "#0x%02x", opnd->prfop->value);
a06ea964
NC
2735 break;
2736
1e6f4800
MW
2737 case AARCH64_OPND_BARRIER_PSB:
2738 snprintf (buf, size, "%s", opnd->hint_option->name);
2739 break;
2740
a06ea964
NC
2741 default:
2742 assert (0);
2743 }
2744}
2745\f
2746#define CPENC(op0,op1,crn,crm,op2) \
2747 ((((op0) << 19) | ((op1) << 16) | ((crn) << 12) | ((crm) << 8) | ((op2) << 5)) >> 5)
2748 /* for 3.9.3 Instructions for Accessing Special Purpose Registers */
2749#define CPEN_(op1,crm,op2) CPENC(3,(op1),4,(crm),(op2))
2750 /* for 3.9.10 System Instructions */
2751#define CPENS(op1,crn,crm,op2) CPENC(1,(op1),(crn),(crm),(op2))
2752
2753#define C0 0
2754#define C1 1
2755#define C2 2
2756#define C3 3
2757#define C4 4
2758#define C5 5
2759#define C6 6
2760#define C7 7
2761#define C8 8
2762#define C9 9
2763#define C10 10
2764#define C11 11
2765#define C12 12
2766#define C13 13
2767#define C14 14
2768#define C15 15
2769
49eec193
YZ
2770#ifdef F_DEPRECATED
2771#undef F_DEPRECATED
2772#endif
2773#define F_DEPRECATED 0x1 /* Deprecated system register. */
2774
f21cce2c
MW
2775#ifdef F_ARCHEXT
2776#undef F_ARCHEXT
2777#endif
2778#define F_ARCHEXT 0x2 /* Architecture dependent system register. */
2779
ea2deeec
MW
2780#ifdef F_HASXT
2781#undef F_HASXT
2782#endif
2783#define F_HASXT 0x4 /* System instruction register <Xt>
2784 operand. */
2785
f21cce2c 2786
a06ea964
NC
2787/* TODO there are two more issues need to be resolved
2788 1. handle read-only and write-only system registers
2789 2. handle cpu-implementation-defined system registers. */
49eec193
YZ
2790const aarch64_sys_reg aarch64_sys_regs [] =
2791{
2792 { "spsr_el1", CPEN_(0,C0,0), 0 }, /* = spsr_svc */
250aafa4 2793 { "spsr_el12", CPEN_ (5, C0, 0), F_ARCHEXT },
49eec193 2794 { "elr_el1", CPEN_(0,C0,1), 0 },
250aafa4 2795 { "elr_el12", CPEN_ (5, C0, 1), F_ARCHEXT },
49eec193
YZ
2796 { "sp_el0", CPEN_(0,C1,0), 0 },
2797 { "spsel", CPEN_(0,C2,0), 0 },
2798 { "daif", CPEN_(3,C2,1), 0 },
2799 { "currentel", CPEN_(0,C2,2), 0 }, /* RO */
f21cce2c 2800 { "pan", CPEN_(0,C2,3), F_ARCHEXT },
6479e48e 2801 { "uao", CPEN_ (0, C2, 4), F_ARCHEXT },
49eec193
YZ
2802 { "nzcv", CPEN_(3,C2,0), 0 },
2803 { "fpcr", CPEN_(3,C4,0), 0 },
2804 { "fpsr", CPEN_(3,C4,1), 0 },
2805 { "dspsr_el0", CPEN_(3,C5,0), 0 },
2806 { "dlr_el0", CPEN_(3,C5,1), 0 },
2807 { "spsr_el2", CPEN_(4,C0,0), 0 }, /* = spsr_hyp */
2808 { "elr_el2", CPEN_(4,C0,1), 0 },
2809 { "sp_el1", CPEN_(4,C1,0), 0 },
2810 { "spsr_irq", CPEN_(4,C3,0), 0 },
2811 { "spsr_abt", CPEN_(4,C3,1), 0 },
2812 { "spsr_und", CPEN_(4,C3,2), 0 },
2813 { "spsr_fiq", CPEN_(4,C3,3), 0 },
2814 { "spsr_el3", CPEN_(6,C0,0), 0 },
2815 { "elr_el3", CPEN_(6,C0,1), 0 },
2816 { "sp_el2", CPEN_(6,C1,0), 0 },
2817 { "spsr_svc", CPEN_(0,C0,0), F_DEPRECATED }, /* = spsr_el1 */
2818 { "spsr_hyp", CPEN_(4,C0,0), F_DEPRECATED }, /* = spsr_el2 */
2819 { "midr_el1", CPENC(3,0,C0,C0,0), 0 }, /* RO */
2820 { "ctr_el0", CPENC(3,3,C0,C0,1), 0 }, /* RO */
2821 { "mpidr_el1", CPENC(3,0,C0,C0,5), 0 }, /* RO */
2822 { "revidr_el1", CPENC(3,0,C0,C0,6), 0 }, /* RO */
2823 { "aidr_el1", CPENC(3,1,C0,C0,7), 0 }, /* RO */
2824 { "dczid_el0", CPENC(3,3,C0,C0,7), 0 }, /* RO */
2825 { "id_dfr0_el1", CPENC(3,0,C0,C1,2), 0 }, /* RO */
2826 { "id_pfr0_el1", CPENC(3,0,C0,C1,0), 0 }, /* RO */
2827 { "id_pfr1_el1", CPENC(3,0,C0,C1,1), 0 }, /* RO */
2828 { "id_afr0_el1", CPENC(3,0,C0,C1,3), 0 }, /* RO */
2829 { "id_mmfr0_el1", CPENC(3,0,C0,C1,4), 0 }, /* RO */
2830 { "id_mmfr1_el1", CPENC(3,0,C0,C1,5), 0 }, /* RO */
2831 { "id_mmfr2_el1", CPENC(3,0,C0,C1,6), 0 }, /* RO */
2832 { "id_mmfr3_el1", CPENC(3,0,C0,C1,7), 0 }, /* RO */
bdfa8b95 2833 { "id_mmfr4_el1", CPENC(3,0,C0,C2,6), 0 }, /* RO */
49eec193
YZ
2834 { "id_isar0_el1", CPENC(3,0,C0,C2,0), 0 }, /* RO */
2835 { "id_isar1_el1", CPENC(3,0,C0,C2,1), 0 }, /* RO */
2836 { "id_isar2_el1", CPENC(3,0,C0,C2,2), 0 }, /* RO */
2837 { "id_isar3_el1", CPENC(3,0,C0,C2,3), 0 }, /* RO */
2838 { "id_isar4_el1", CPENC(3,0,C0,C2,4), 0 }, /* RO */
2839 { "id_isar5_el1", CPENC(3,0,C0,C2,5), 0 }, /* RO */
2840 { "mvfr0_el1", CPENC(3,0,C0,C3,0), 0 }, /* RO */
2841 { "mvfr1_el1", CPENC(3,0,C0,C3,1), 0 }, /* RO */
2842 { "mvfr2_el1", CPENC(3,0,C0,C3,2), 0 }, /* RO */
2843 { "ccsidr_el1", CPENC(3,1,C0,C0,0), 0 }, /* RO */
2844 { "id_aa64pfr0_el1", CPENC(3,0,C0,C4,0), 0 }, /* RO */
2845 { "id_aa64pfr1_el1", CPENC(3,0,C0,C4,1), 0 }, /* RO */
2846 { "id_aa64dfr0_el1", CPENC(3,0,C0,C5,0), 0 }, /* RO */
2847 { "id_aa64dfr1_el1", CPENC(3,0,C0,C5,1), 0 }, /* RO */
2848 { "id_aa64isar0_el1", CPENC(3,0,C0,C6,0), 0 }, /* RO */
2849 { "id_aa64isar1_el1", CPENC(3,0,C0,C6,1), 0 }, /* RO */
2850 { "id_aa64mmfr0_el1", CPENC(3,0,C0,C7,0), 0 }, /* RO */
2851 { "id_aa64mmfr1_el1", CPENC(3,0,C0,C7,1), 0 }, /* RO */
1a04d1a7 2852 { "id_aa64mmfr2_el1", CPENC (3, 0, C0, C7, 2), F_ARCHEXT }, /* RO */
49eec193
YZ
2853 { "id_aa64afr0_el1", CPENC(3,0,C0,C5,4), 0 }, /* RO */
2854 { "id_aa64afr1_el1", CPENC(3,0,C0,C5,5), 0 }, /* RO */
2855 { "clidr_el1", CPENC(3,1,C0,C0,1), 0 }, /* RO */
2856 { "csselr_el1", CPENC(3,2,C0,C0,0), 0 }, /* RO */
2857 { "vpidr_el2", CPENC(3,4,C0,C0,0), 0 },
2858 { "vmpidr_el2", CPENC(3,4,C0,C0,5), 0 },
2859 { "sctlr_el1", CPENC(3,0,C1,C0,0), 0 },
2860 { "sctlr_el2", CPENC(3,4,C1,C0,0), 0 },
2861 { "sctlr_el3", CPENC(3,6,C1,C0,0), 0 },
250aafa4 2862 { "sctlr_el12", CPENC (3, 5, C1, C0, 0), F_ARCHEXT },
49eec193
YZ
2863 { "actlr_el1", CPENC(3,0,C1,C0,1), 0 },
2864 { "actlr_el2", CPENC(3,4,C1,C0,1), 0 },
2865 { "actlr_el3", CPENC(3,6,C1,C0,1), 0 },
2866 { "cpacr_el1", CPENC(3,0,C1,C0,2), 0 },
250aafa4 2867 { "cpacr_el12", CPENC (3, 5, C1, C0, 2), F_ARCHEXT },
49eec193
YZ
2868 { "cptr_el2", CPENC(3,4,C1,C1,2), 0 },
2869 { "cptr_el3", CPENC(3,6,C1,C1,2), 0 },
2870 { "scr_el3", CPENC(3,6,C1,C1,0), 0 },
2871 { "hcr_el2", CPENC(3,4,C1,C1,0), 0 },
2872 { "mdcr_el2", CPENC(3,4,C1,C1,1), 0 },
2873 { "mdcr_el3", CPENC(3,6,C1,C3,1), 0 },
2874 { "hstr_el2", CPENC(3,4,C1,C1,3), 0 },
2875 { "hacr_el2", CPENC(3,4,C1,C1,7), 0 },
2876 { "ttbr0_el1", CPENC(3,0,C2,C0,0), 0 },
2877 { "ttbr1_el1", CPENC(3,0,C2,C0,1), 0 },
2878 { "ttbr0_el2", CPENC(3,4,C2,C0,0), 0 },
250aafa4 2879 { "ttbr1_el2", CPENC (3, 4, C2, C0, 1), F_ARCHEXT },
49eec193 2880 { "ttbr0_el3", CPENC(3,6,C2,C0,0), 0 },
250aafa4
MW
2881 { "ttbr0_el12", CPENC (3, 5, C2, C0, 0), F_ARCHEXT },
2882 { "ttbr1_el12", CPENC (3, 5, C2, C0, 1), F_ARCHEXT },
49eec193
YZ
2883 { "vttbr_el2", CPENC(3,4,C2,C1,0), 0 },
2884 { "tcr_el1", CPENC(3,0,C2,C0,2), 0 },
2885 { "tcr_el2", CPENC(3,4,C2,C0,2), 0 },
2886 { "tcr_el3", CPENC(3,6,C2,C0,2), 0 },
250aafa4 2887 { "tcr_el12", CPENC (3, 5, C2, C0, 2), F_ARCHEXT },
49eec193
YZ
2888 { "vtcr_el2", CPENC(3,4,C2,C1,2), 0 },
2889 { "afsr0_el1", CPENC(3,0,C5,C1,0), 0 },
2890 { "afsr1_el1", CPENC(3,0,C5,C1,1), 0 },
2891 { "afsr0_el2", CPENC(3,4,C5,C1,0), 0 },
2892 { "afsr1_el2", CPENC(3,4,C5,C1,1), 0 },
2893 { "afsr0_el3", CPENC(3,6,C5,C1,0), 0 },
250aafa4 2894 { "afsr0_el12", CPENC (3, 5, C5, C1, 0), F_ARCHEXT },
49eec193 2895 { "afsr1_el3", CPENC(3,6,C5,C1,1), 0 },
250aafa4 2896 { "afsr1_el12", CPENC (3, 5, C5, C1, 1), F_ARCHEXT },
49eec193
YZ
2897 { "esr_el1", CPENC(3,0,C5,C2,0), 0 },
2898 { "esr_el2", CPENC(3,4,C5,C2,0), 0 },
2899 { "esr_el3", CPENC(3,6,C5,C2,0), 0 },
250aafa4 2900 { "esr_el12", CPENC (3, 5, C5, C2, 0), F_ARCHEXT },
47f81142 2901 { "vsesr_el2", CPENC (3, 4, C5, C2, 3), F_ARCHEXT }, /* RO */
49eec193 2902 { "fpexc32_el2", CPENC(3,4,C5,C3,0), 0 },
47f81142
MW
2903 { "erridr_el1", CPENC (3, 0, C5, C3, 0), F_ARCHEXT }, /* RO */
2904 { "errselr_el1", CPENC (3, 0, C5, C3, 1), F_ARCHEXT },
2905 { "erxfr_el1", CPENC (3, 0, C5, C4, 0), F_ARCHEXT }, /* RO */
2906 { "erxctlr_el1", CPENC (3, 0, C5, C4, 1), F_ARCHEXT },
2907 { "erxstatus_el1", CPENC (3, 0, C5, C4, 2), F_ARCHEXT },
2908 { "erxaddr_el1", CPENC (3, 0, C5, C4, 3), F_ARCHEXT },
2909 { "erxmisc0_el1", CPENC (3, 0, C5, C5, 0), F_ARCHEXT },
2910 { "erxmisc1_el1", CPENC (3, 0, C5, C5, 1), F_ARCHEXT },
49eec193
YZ
2911 { "far_el1", CPENC(3,0,C6,C0,0), 0 },
2912 { "far_el2", CPENC(3,4,C6,C0,0), 0 },
2913 { "far_el3", CPENC(3,6,C6,C0,0), 0 },
250aafa4 2914 { "far_el12", CPENC (3, 5, C6, C0, 0), F_ARCHEXT },
49eec193
YZ
2915 { "hpfar_el2", CPENC(3,4,C6,C0,4), 0 },
2916 { "par_el1", CPENC(3,0,C7,C4,0), 0 },
2917 { "mair_el1", CPENC(3,0,C10,C2,0), 0 },
2918 { "mair_el2", CPENC(3,4,C10,C2,0), 0 },
2919 { "mair_el3", CPENC(3,6,C10,C2,0), 0 },
250aafa4 2920 { "mair_el12", CPENC (3, 5, C10, C2, 0), F_ARCHEXT },
49eec193
YZ
2921 { "amair_el1", CPENC(3,0,C10,C3,0), 0 },
2922 { "amair_el2", CPENC(3,4,C10,C3,0), 0 },
2923 { "amair_el3", CPENC(3,6,C10,C3,0), 0 },
250aafa4 2924 { "amair_el12", CPENC (3, 5, C10, C3, 0), F_ARCHEXT },
49eec193
YZ
2925 { "vbar_el1", CPENC(3,0,C12,C0,0), 0 },
2926 { "vbar_el2", CPENC(3,4,C12,C0,0), 0 },
2927 { "vbar_el3", CPENC(3,6,C12,C0,0), 0 },
250aafa4 2928 { "vbar_el12", CPENC (3, 5, C12, C0, 0), F_ARCHEXT },
49eec193
YZ
2929 { "rvbar_el1", CPENC(3,0,C12,C0,1), 0 }, /* RO */
2930 { "rvbar_el2", CPENC(3,4,C12,C0,1), 0 }, /* RO */
2931 { "rvbar_el3", CPENC(3,6,C12,C0,1), 0 }, /* RO */
2932 { "rmr_el1", CPENC(3,0,C12,C0,2), 0 },
2933 { "rmr_el2", CPENC(3,4,C12,C0,2), 0 },
2934 { "rmr_el3", CPENC(3,6,C12,C0,2), 0 },
2935 { "isr_el1", CPENC(3,0,C12,C1,0), 0 }, /* RO */
47f81142
MW
2936 { "disr_el1", CPENC (3, 0, C12, C1, 1), F_ARCHEXT },
2937 { "vdisr_el2", CPENC (3, 4, C12, C1, 1), F_ARCHEXT },
49eec193 2938 { "contextidr_el1", CPENC(3,0,C13,C0,1), 0 },
250aafa4
MW
2939 { "contextidr_el2", CPENC (3, 4, C13, C0, 1), F_ARCHEXT },
2940 { "contextidr_el12", CPENC (3, 5, C13, C0, 1), F_ARCHEXT },
49eec193
YZ
2941 { "tpidr_el0", CPENC(3,3,C13,C0,2), 0 },
2942 { "tpidrro_el0", CPENC(3,3,C13,C0,3), 0 }, /* RO */
2943 { "tpidr_el1", CPENC(3,0,C13,C0,4), 0 },
2944 { "tpidr_el2", CPENC(3,4,C13,C0,2), 0 },
2945 { "tpidr_el3", CPENC(3,6,C13,C0,2), 0 },
2946 { "teecr32_el1", CPENC(2,2,C0, C0,0), 0 }, /* See section 3.9.7.1 */
2947 { "cntfrq_el0", CPENC(3,3,C14,C0,0), 0 }, /* RO */
2948 { "cntpct_el0", CPENC(3,3,C14,C0,1), 0 }, /* RO */
2949 { "cntvct_el0", CPENC(3,3,C14,C0,2), 0 }, /* RO */
2950 { "cntvoff_el2", CPENC(3,4,C14,C0,3), 0 },
2951 { "cntkctl_el1", CPENC(3,0,C14,C1,0), 0 },
250aafa4 2952 { "cntkctl_el12", CPENC (3, 5, C14, C1, 0), F_ARCHEXT },
49eec193
YZ
2953 { "cnthctl_el2", CPENC(3,4,C14,C1,0), 0 },
2954 { "cntp_tval_el0", CPENC(3,3,C14,C2,0), 0 },
250aafa4 2955 { "cntp_tval_el02", CPENC (3, 5, C14, C2, 0), F_ARCHEXT },
49eec193 2956 { "cntp_ctl_el0", CPENC(3,3,C14,C2,1), 0 },
250aafa4 2957 { "cntp_ctl_el02", CPENC (3, 5, C14, C2, 1), F_ARCHEXT },
49eec193 2958 { "cntp_cval_el0", CPENC(3,3,C14,C2,2), 0 },
250aafa4 2959 { "cntp_cval_el02", CPENC (3, 5, C14, C2, 2), F_ARCHEXT },
49eec193 2960 { "cntv_tval_el0", CPENC(3,3,C14,C3,0), 0 },
250aafa4 2961 { "cntv_tval_el02", CPENC (3, 5, C14, C3, 0), F_ARCHEXT },
49eec193 2962 { "cntv_ctl_el0", CPENC(3,3,C14,C3,1), 0 },
250aafa4 2963 { "cntv_ctl_el02", CPENC (3, 5, C14, C3, 1), F_ARCHEXT },
49eec193 2964 { "cntv_cval_el0", CPENC(3,3,C14,C3,2), 0 },
250aafa4 2965 { "cntv_cval_el02", CPENC (3, 5, C14, C3, 2), F_ARCHEXT },
49eec193
YZ
2966 { "cnthp_tval_el2", CPENC(3,4,C14,C2,0), 0 },
2967 { "cnthp_ctl_el2", CPENC(3,4,C14,C2,1), 0 },
2968 { "cnthp_cval_el2", CPENC(3,4,C14,C2,2), 0 },
2969 { "cntps_tval_el1", CPENC(3,7,C14,C2,0), 0 },
2970 { "cntps_ctl_el1", CPENC(3,7,C14,C2,1), 0 },
2971 { "cntps_cval_el1", CPENC(3,7,C14,C2,2), 0 },
250aafa4
MW
2972 { "cnthv_tval_el2", CPENC (3, 4, C14, C3, 0), F_ARCHEXT },
2973 { "cnthv_ctl_el2", CPENC (3, 4, C14, C3, 1), F_ARCHEXT },
2974 { "cnthv_cval_el2", CPENC (3, 4, C14, C3, 2), F_ARCHEXT },
49eec193
YZ
2975 { "dacr32_el2", CPENC(3,4,C3,C0,0), 0 },
2976 { "ifsr32_el2", CPENC(3,4,C5,C0,1), 0 },
2977 { "teehbr32_el1", CPENC(2,2,C1,C0,0), 0 },
2978 { "sder32_el3", CPENC(3,6,C1,C1,1), 0 },
2979 { "mdscr_el1", CPENC(2,0,C0, C2, 2), 0 },
2980 { "mdccsr_el0", CPENC(2,3,C0, C1, 0), 0 }, /* r */
2981 { "mdccint_el1", CPENC(2,0,C0, C2, 0), 0 },
2982 { "dbgdtr_el0", CPENC(2,3,C0, C4, 0), 0 },
2983 { "dbgdtrrx_el0", CPENC(2,3,C0, C5, 0), 0 }, /* r */
2984 { "dbgdtrtx_el0", CPENC(2,3,C0, C5, 0), 0 }, /* w */
2985 { "osdtrrx_el1", CPENC(2,0,C0, C0, 2), 0 }, /* r */
2986 { "osdtrtx_el1", CPENC(2,0,C0, C3, 2), 0 }, /* w */
2987 { "oseccr_el1", CPENC(2,0,C0, C6, 2), 0 },
2988 { "dbgvcr32_el2", CPENC(2,4,C0, C7, 0), 0 },
2989 { "dbgbvr0_el1", CPENC(2,0,C0, C0, 4), 0 },
2990 { "dbgbvr1_el1", CPENC(2,0,C0, C1, 4), 0 },
2991 { "dbgbvr2_el1", CPENC(2,0,C0, C2, 4), 0 },
2992 { "dbgbvr3_el1", CPENC(2,0,C0, C3, 4), 0 },
2993 { "dbgbvr4_el1", CPENC(2,0,C0, C4, 4), 0 },
2994 { "dbgbvr5_el1", CPENC(2,0,C0, C5, 4), 0 },
2995 { "dbgbvr6_el1", CPENC(2,0,C0, C6, 4), 0 },
2996 { "dbgbvr7_el1", CPENC(2,0,C0, C7, 4), 0 },
2997 { "dbgbvr8_el1", CPENC(2,0,C0, C8, 4), 0 },
2998 { "dbgbvr9_el1", CPENC(2,0,C0, C9, 4), 0 },
2999 { "dbgbvr10_el1", CPENC(2,0,C0, C10,4), 0 },
3000 { "dbgbvr11_el1", CPENC(2,0,C0, C11,4), 0 },
3001 { "dbgbvr12_el1", CPENC(2,0,C0, C12,4), 0 },
3002 { "dbgbvr13_el1", CPENC(2,0,C0, C13,4), 0 },
3003 { "dbgbvr14_el1", CPENC(2,0,C0, C14,4), 0 },
3004 { "dbgbvr15_el1", CPENC(2,0,C0, C15,4), 0 },
3005 { "dbgbcr0_el1", CPENC(2,0,C0, C0, 5), 0 },
3006 { "dbgbcr1_el1", CPENC(2,0,C0, C1, 5), 0 },
3007 { "dbgbcr2_el1", CPENC(2,0,C0, C2, 5), 0 },
3008 { "dbgbcr3_el1", CPENC(2,0,C0, C3, 5), 0 },
3009 { "dbgbcr4_el1", CPENC(2,0,C0, C4, 5), 0 },
3010 { "dbgbcr5_el1", CPENC(2,0,C0, C5, 5), 0 },
3011 { "dbgbcr6_el1", CPENC(2,0,C0, C6, 5), 0 },
3012 { "dbgbcr7_el1", CPENC(2,0,C0, C7, 5), 0 },
3013 { "dbgbcr8_el1", CPENC(2,0,C0, C8, 5), 0 },
3014 { "dbgbcr9_el1", CPENC(2,0,C0, C9, 5), 0 },
3015 { "dbgbcr10_el1", CPENC(2,0,C0, C10,5), 0 },
3016 { "dbgbcr11_el1", CPENC(2,0,C0, C11,5), 0 },
3017 { "dbgbcr12_el1", CPENC(2,0,C0, C12,5), 0 },
3018 { "dbgbcr13_el1", CPENC(2,0,C0, C13,5), 0 },
3019 { "dbgbcr14_el1", CPENC(2,0,C0, C14,5), 0 },
3020 { "dbgbcr15_el1", CPENC(2,0,C0, C15,5), 0 },
3021 { "dbgwvr0_el1", CPENC(2,0,C0, C0, 6), 0 },
3022 { "dbgwvr1_el1", CPENC(2,0,C0, C1, 6), 0 },
3023 { "dbgwvr2_el1", CPENC(2,0,C0, C2, 6), 0 },
3024 { "dbgwvr3_el1", CPENC(2,0,C0, C3, 6), 0 },
3025 { "dbgwvr4_el1", CPENC(2,0,C0, C4, 6), 0 },
3026 { "dbgwvr5_el1", CPENC(2,0,C0, C5, 6), 0 },
3027 { "dbgwvr6_el1", CPENC(2,0,C0, C6, 6), 0 },
3028 { "dbgwvr7_el1", CPENC(2,0,C0, C7, 6), 0 },
3029 { "dbgwvr8_el1", CPENC(2,0,C0, C8, 6), 0 },
3030 { "dbgwvr9_el1", CPENC(2,0,C0, C9, 6), 0 },
3031 { "dbgwvr10_el1", CPENC(2,0,C0, C10,6), 0 },
3032 { "dbgwvr11_el1", CPENC(2,0,C0, C11,6), 0 },
3033 { "dbgwvr12_el1", CPENC(2,0,C0, C12,6), 0 },
3034 { "dbgwvr13_el1", CPENC(2,0,C0, C13,6), 0 },
3035 { "dbgwvr14_el1", CPENC(2,0,C0, C14,6), 0 },
3036 { "dbgwvr15_el1", CPENC(2,0,C0, C15,6), 0 },
3037 { "dbgwcr0_el1", CPENC(2,0,C0, C0, 7), 0 },
3038 { "dbgwcr1_el1", CPENC(2,0,C0, C1, 7), 0 },
3039 { "dbgwcr2_el1", CPENC(2,0,C0, C2, 7), 0 },
3040 { "dbgwcr3_el1", CPENC(2,0,C0, C3, 7), 0 },
3041 { "dbgwcr4_el1", CPENC(2,0,C0, C4, 7), 0 },
3042 { "dbgwcr5_el1", CPENC(2,0,C0, C5, 7), 0 },
3043 { "dbgwcr6_el1", CPENC(2,0,C0, C6, 7), 0 },
3044 { "dbgwcr7_el1", CPENC(2,0,C0, C7, 7), 0 },
3045 { "dbgwcr8_el1", CPENC(2,0,C0, C8, 7), 0 },
3046 { "dbgwcr9_el1", CPENC(2,0,C0, C9, 7), 0 },
3047 { "dbgwcr10_el1", CPENC(2,0,C0, C10,7), 0 },
3048 { "dbgwcr11_el1", CPENC(2,0,C0, C11,7), 0 },
3049 { "dbgwcr12_el1", CPENC(2,0,C0, C12,7), 0 },
3050 { "dbgwcr13_el1", CPENC(2,0,C0, C13,7), 0 },
3051 { "dbgwcr14_el1", CPENC(2,0,C0, C14,7), 0 },
3052 { "dbgwcr15_el1", CPENC(2,0,C0, C15,7), 0 },
3053 { "mdrar_el1", CPENC(2,0,C1, C0, 0), 0 }, /* r */
3054 { "oslar_el1", CPENC(2,0,C1, C0, 4), 0 }, /* w */
3055 { "oslsr_el1", CPENC(2,0,C1, C1, 4), 0 }, /* r */
3056 { "osdlr_el1", CPENC(2,0,C1, C3, 4), 0 },
3057 { "dbgprcr_el1", CPENC(2,0,C1, C4, 4), 0 },
3058 { "dbgclaimset_el1", CPENC(2,0,C7, C8, 6), 0 },
3059 { "dbgclaimclr_el1", CPENC(2,0,C7, C9, 6), 0 },
3060 { "dbgauthstatus_el1", CPENC(2,0,C7, C14,6), 0 }, /* r */
55c144e6
MW
3061 { "pmblimitr_el1", CPENC (3, 0, C9, C10, 0), F_ARCHEXT }, /* rw */
3062 { "pmbptr_el1", CPENC (3, 0, C9, C10, 1), F_ARCHEXT }, /* rw */
3063 { "pmbsr_el1", CPENC (3, 0, C9, C10, 3), F_ARCHEXT }, /* rw */
3064 { "pmbidr_el1", CPENC (3, 0, C9, C10, 7), F_ARCHEXT }, /* ro */
3065 { "pmscr_el1", CPENC (3, 0, C9, C9, 0), F_ARCHEXT }, /* rw */
3066 { "pmsicr_el1", CPENC (3, 0, C9, C9, 2), F_ARCHEXT }, /* rw */
3067 { "pmsirr_el1", CPENC (3, 0, C9, C9, 3), F_ARCHEXT }, /* rw */
3068 { "pmsfcr_el1", CPENC (3, 0, C9, C9, 4), F_ARCHEXT }, /* rw */
3069 { "pmsevfr_el1", CPENC (3, 0, C9, C9, 5), F_ARCHEXT }, /* rw */
3070 { "pmslatfr_el1", CPENC (3, 0, C9, C9, 6), F_ARCHEXT }, /* rw */
3071 { "pmsidr_el1", CPENC (3, 0, C9, C9, 7), F_ARCHEXT }, /* ro */
3072 { "pmscr_el2", CPENC (3, 4, C9, C9, 0), F_ARCHEXT }, /* rw */
3073 { "pmscr_el12", CPENC (3, 5, C9, C9, 0), F_ARCHEXT }, /* rw */
49eec193
YZ
3074 { "pmcr_el0", CPENC(3,3,C9,C12, 0), 0 },
3075 { "pmcntenset_el0", CPENC(3,3,C9,C12, 1), 0 },
3076 { "pmcntenclr_el0", CPENC(3,3,C9,C12, 2), 0 },
3077 { "pmovsclr_el0", CPENC(3,3,C9,C12, 3), 0 },
3078 { "pmswinc_el0", CPENC(3,3,C9,C12, 4), 0 }, /* w */
3079 { "pmselr_el0", CPENC(3,3,C9,C12, 5), 0 },
3080 { "pmceid0_el0", CPENC(3,3,C9,C12, 6), 0 }, /* r */
3081 { "pmceid1_el0", CPENC(3,3,C9,C12, 7), 0 }, /* r */
3082 { "pmccntr_el0", CPENC(3,3,C9,C13, 0), 0 },
3083 { "pmxevtyper_el0", CPENC(3,3,C9,C13, 1), 0 },
3084 { "pmxevcntr_el0", CPENC(3,3,C9,C13, 2), 0 },
3085 { "pmuserenr_el0", CPENC(3,3,C9,C14, 0), 0 },
3086 { "pmintenset_el1", CPENC(3,0,C9,C14, 1), 0 },
3087 { "pmintenclr_el1", CPENC(3,0,C9,C14, 2), 0 },
3088 { "pmovsset_el0", CPENC(3,3,C9,C14, 3), 0 },
3089 { "pmevcntr0_el0", CPENC(3,3,C14,C8, 0), 0 },
3090 { "pmevcntr1_el0", CPENC(3,3,C14,C8, 1), 0 },
3091 { "pmevcntr2_el0", CPENC(3,3,C14,C8, 2), 0 },
3092 { "pmevcntr3_el0", CPENC(3,3,C14,C8, 3), 0 },
3093 { "pmevcntr4_el0", CPENC(3,3,C14,C8, 4), 0 },
3094 { "pmevcntr5_el0", CPENC(3,3,C14,C8, 5), 0 },
3095 { "pmevcntr6_el0", CPENC(3,3,C14,C8, 6), 0 },
3096 { "pmevcntr7_el0", CPENC(3,3,C14,C8, 7), 0 },
3097 { "pmevcntr8_el0", CPENC(3,3,C14,C9, 0), 0 },
3098 { "pmevcntr9_el0", CPENC(3,3,C14,C9, 1), 0 },
3099 { "pmevcntr10_el0", CPENC(3,3,C14,C9, 2), 0 },
3100 { "pmevcntr11_el0", CPENC(3,3,C14,C9, 3), 0 },
3101 { "pmevcntr12_el0", CPENC(3,3,C14,C9, 4), 0 },
3102 { "pmevcntr13_el0", CPENC(3,3,C14,C9, 5), 0 },
3103 { "pmevcntr14_el0", CPENC(3,3,C14,C9, 6), 0 },
3104 { "pmevcntr15_el0", CPENC(3,3,C14,C9, 7), 0 },
3105 { "pmevcntr16_el0", CPENC(3,3,C14,C10,0), 0 },
3106 { "pmevcntr17_el0", CPENC(3,3,C14,C10,1), 0 },
3107 { "pmevcntr18_el0", CPENC(3,3,C14,C10,2), 0 },
3108 { "pmevcntr19_el0", CPENC(3,3,C14,C10,3), 0 },
3109 { "pmevcntr20_el0", CPENC(3,3,C14,C10,4), 0 },
3110 { "pmevcntr21_el0", CPENC(3,3,C14,C10,5), 0 },
3111 { "pmevcntr22_el0", CPENC(3,3,C14,C10,6), 0 },
3112 { "pmevcntr23_el0", CPENC(3,3,C14,C10,7), 0 },
3113 { "pmevcntr24_el0", CPENC(3,3,C14,C11,0), 0 },
3114 { "pmevcntr25_el0", CPENC(3,3,C14,C11,1), 0 },
3115 { "pmevcntr26_el0", CPENC(3,3,C14,C11,2), 0 },
3116 { "pmevcntr27_el0", CPENC(3,3,C14,C11,3), 0 },
3117 { "pmevcntr28_el0", CPENC(3,3,C14,C11,4), 0 },
3118 { "pmevcntr29_el0", CPENC(3,3,C14,C11,5), 0 },
3119 { "pmevcntr30_el0", CPENC(3,3,C14,C11,6), 0 },
3120 { "pmevtyper0_el0", CPENC(3,3,C14,C12,0), 0 },
3121 { "pmevtyper1_el0", CPENC(3,3,C14,C12,1), 0 },
3122 { "pmevtyper2_el0", CPENC(3,3,C14,C12,2), 0 },
3123 { "pmevtyper3_el0", CPENC(3,3,C14,C12,3), 0 },
3124 { "pmevtyper4_el0", CPENC(3,3,C14,C12,4), 0 },
3125 { "pmevtyper5_el0", CPENC(3,3,C14,C12,5), 0 },
3126 { "pmevtyper6_el0", CPENC(3,3,C14,C12,6), 0 },
3127 { "pmevtyper7_el0", CPENC(3,3,C14,C12,7), 0 },
3128 { "pmevtyper8_el0", CPENC(3,3,C14,C13,0), 0 },
3129 { "pmevtyper9_el0", CPENC(3,3,C14,C13,1), 0 },
3130 { "pmevtyper10_el0", CPENC(3,3,C14,C13,2), 0 },
3131 { "pmevtyper11_el0", CPENC(3,3,C14,C13,3), 0 },
3132 { "pmevtyper12_el0", CPENC(3,3,C14,C13,4), 0 },
3133 { "pmevtyper13_el0", CPENC(3,3,C14,C13,5), 0 },
3134 { "pmevtyper14_el0", CPENC(3,3,C14,C13,6), 0 },
3135 { "pmevtyper15_el0", CPENC(3,3,C14,C13,7), 0 },
3136 { "pmevtyper16_el0", CPENC(3,3,C14,C14,0), 0 },
3137 { "pmevtyper17_el0", CPENC(3,3,C14,C14,1), 0 },
3138 { "pmevtyper18_el0", CPENC(3,3,C14,C14,2), 0 },
3139 { "pmevtyper19_el0", CPENC(3,3,C14,C14,3), 0 },
3140 { "pmevtyper20_el0", CPENC(3,3,C14,C14,4), 0 },
3141 { "pmevtyper21_el0", CPENC(3,3,C14,C14,5), 0 },
3142 { "pmevtyper22_el0", CPENC(3,3,C14,C14,6), 0 },
3143 { "pmevtyper23_el0", CPENC(3,3,C14,C14,7), 0 },
3144 { "pmevtyper24_el0", CPENC(3,3,C14,C15,0), 0 },
3145 { "pmevtyper25_el0", CPENC(3,3,C14,C15,1), 0 },
3146 { "pmevtyper26_el0", CPENC(3,3,C14,C15,2), 0 },
3147 { "pmevtyper27_el0", CPENC(3,3,C14,C15,3), 0 },
3148 { "pmevtyper28_el0", CPENC(3,3,C14,C15,4), 0 },
3149 { "pmevtyper29_el0", CPENC(3,3,C14,C15,5), 0 },
3150 { "pmevtyper30_el0", CPENC(3,3,C14,C15,6), 0 },
3151 { "pmccfiltr_el0", CPENC(3,3,C14,C15,7), 0 },
3152 { 0, CPENC(0,0,0,0,0), 0 },
a06ea964
NC
3153};
3154
49eec193
YZ
3155bfd_boolean
3156aarch64_sys_reg_deprecated_p (const aarch64_sys_reg *reg)
3157{
3158 return (reg->flags & F_DEPRECATED) != 0;
3159}
3160
f21cce2c
MW
3161bfd_boolean
3162aarch64_sys_reg_supported_p (const aarch64_feature_set features,
3163 const aarch64_sys_reg *reg)
3164{
3165 if (!(reg->flags & F_ARCHEXT))
3166 return TRUE;
3167
3168 /* PAN. Values are from aarch64_sys_regs. */
3169 if (reg->value == CPEN_(0,C2,3)
3170 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_PAN))
3171 return FALSE;
3172
250aafa4
MW
3173 /* Virtualization host extensions: system registers. */
3174 if ((reg->value == CPENC (3, 4, C2, C0, 1)
3175 || reg->value == CPENC (3, 4, C13, C0, 1)
3176 || reg->value == CPENC (3, 4, C14, C3, 0)
3177 || reg->value == CPENC (3, 4, C14, C3, 1)
3178 || reg->value == CPENC (3, 4, C14, C3, 2))
3179 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_1))
3180 return FALSE;
3181
3182 /* Virtualization host extensions: *_el12 names of *_el1 registers. */
3183 if ((reg->value == CPEN_ (5, C0, 0)
3184 || reg->value == CPEN_ (5, C0, 1)
3185 || reg->value == CPENC (3, 5, C1, C0, 0)
3186 || reg->value == CPENC (3, 5, C1, C0, 2)
3187 || reg->value == CPENC (3, 5, C2, C0, 0)
3188 || reg->value == CPENC (3, 5, C2, C0, 1)
3189 || reg->value == CPENC (3, 5, C2, C0, 2)
3190 || reg->value == CPENC (3, 5, C5, C1, 0)
3191 || reg->value == CPENC (3, 5, C5, C1, 1)
3192 || reg->value == CPENC (3, 5, C5, C2, 0)
3193 || reg->value == CPENC (3, 5, C6, C0, 0)
3194 || reg->value == CPENC (3, 5, C10, C2, 0)
3195 || reg->value == CPENC (3, 5, C10, C3, 0)
3196 || reg->value == CPENC (3, 5, C12, C0, 0)
3197 || reg->value == CPENC (3, 5, C13, C0, 1)
3198 || reg->value == CPENC (3, 5, C14, C1, 0))
3199 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_1))
3200 return FALSE;
3201
3202 /* Virtualization host extensions: *_el02 names of *_el0 registers. */
3203 if ((reg->value == CPENC (3, 5, C14, C2, 0)
3204 || reg->value == CPENC (3, 5, C14, C2, 1)
3205 || reg->value == CPENC (3, 5, C14, C2, 2)
3206 || reg->value == CPENC (3, 5, C14, C3, 0)
3207 || reg->value == CPENC (3, 5, C14, C3, 1)
3208 || reg->value == CPENC (3, 5, C14, C3, 2))
3209 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_1))
63511907 3210 return FALSE;
1a04d1a7
MW
3211
3212 /* ARMv8.2 features. */
6479e48e
MW
3213
3214 /* ID_AA64MMFR2_EL1. */
1a04d1a7
MW
3215 if (reg->value == CPENC (3, 0, C0, C7, 2)
3216 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
250aafa4
MW
3217 return FALSE;
3218
6479e48e
MW
3219 /* PSTATE.UAO. */
3220 if (reg->value == CPEN_ (0, C2, 4)
3221 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
3222 return FALSE;
3223
47f81142
MW
3224 /* RAS extension. */
3225
651657fa
MW
3226 /* ERRIDR_EL1, ERRSELR_EL1, ERXFR_EL1, ERXCTLR_EL1, ERXSTATUS_EL, ERXADDR_EL1,
3227 ERXMISC0_EL1 AND ERXMISC1_EL1. */
47f81142 3228 if ((reg->value == CPENC (3, 0, C5, C3, 0)
651657fa 3229 || reg->value == CPENC (3, 0, C5, C3, 1)
47f81142
MW
3230 || reg->value == CPENC (3, 0, C5, C3, 2)
3231 || reg->value == CPENC (3, 0, C5, C3, 3)
651657fa
MW
3232 || reg->value == CPENC (3, 0, C5, C4, 0)
3233 || reg->value == CPENC (3, 0, C5, C4, 1)
3234 || reg->value == CPENC (3, 0, C5, C4, 2)
3235 || reg->value == CPENC (3, 0, C5, C4, 3)
47f81142
MW
3236 || reg->value == CPENC (3, 0, C5, C5, 0)
3237 || reg->value == CPENC (3, 0, C5, C5, 1))
3238 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_RAS))
3239 return FALSE;
3240
3241 /* VSESR_EL2, DISR_EL1 and VDISR_EL2. */
3242 if ((reg->value == CPENC (3, 4, C5, C2, 3)
3243 || reg->value == CPENC (3, 0, C12, C1, 1)
3244 || reg->value == CPENC (3, 4, C12, C1, 1))
3245 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_RAS))
3246 return FALSE;
3247
55c144e6
MW
3248 /* Statistical Profiling extension. */
3249 if ((reg->value == CPENC (3, 0, C9, C10, 0)
3250 || reg->value == CPENC (3, 0, C9, C10, 1)
3251 || reg->value == CPENC (3, 0, C9, C10, 3)
3252 || reg->value == CPENC (3, 0, C9, C10, 7)
3253 || reg->value == CPENC (3, 0, C9, C9, 0)
3254 || reg->value == CPENC (3, 0, C9, C9, 2)
3255 || reg->value == CPENC (3, 0, C9, C9, 3)
3256 || reg->value == CPENC (3, 0, C9, C9, 4)
3257 || reg->value == CPENC (3, 0, C9, C9, 5)
3258 || reg->value == CPENC (3, 0, C9, C9, 6)
3259 || reg->value == CPENC (3, 0, C9, C9, 7)
3260 || reg->value == CPENC (3, 4, C9, C9, 0)
3261 || reg->value == CPENC (3, 5, C9, C9, 0))
3262 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_PROFILE))
3263 return FALSE;
3264
f21cce2c
MW
3265 return TRUE;
3266}
3267
87b8eed7 3268const aarch64_sys_reg aarch64_pstatefields [] =
a06ea964 3269{
87b8eed7
YZ
3270 { "spsel", 0x05, 0 },
3271 { "daifset", 0x1e, 0 },
3272 { "daifclr", 0x1f, 0 },
f21cce2c 3273 { "pan", 0x04, F_ARCHEXT },
6479e48e 3274 { "uao", 0x03, F_ARCHEXT },
87b8eed7 3275 { 0, CPENC(0,0,0,0,0), 0 },
a06ea964
NC
3276};
3277
f21cce2c
MW
3278bfd_boolean
3279aarch64_pstatefield_supported_p (const aarch64_feature_set features,
3280 const aarch64_sys_reg *reg)
3281{
3282 if (!(reg->flags & F_ARCHEXT))
3283 return TRUE;
3284
3285 /* PAN. Values are from aarch64_pstatefields. */
3286 if (reg->value == 0x04
3287 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_PAN))
3288 return FALSE;
3289
6479e48e
MW
3290 /* UAO. Values are from aarch64_pstatefields. */
3291 if (reg->value == 0x03
3292 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
3293 return FALSE;
3294
f21cce2c
MW
3295 return TRUE;
3296}
3297
a06ea964
NC
3298const aarch64_sys_ins_reg aarch64_sys_regs_ic[] =
3299{
3300 { "ialluis", CPENS(0,C7,C1,0), 0 },
3301 { "iallu", CPENS(0,C7,C5,0), 0 },
ea2deeec 3302 { "ivau", CPENS (3, C7, C5, 1), F_HASXT },
a06ea964
NC
3303 { 0, CPENS(0,0,0,0), 0 }
3304};
3305
3306const aarch64_sys_ins_reg aarch64_sys_regs_dc[] =
3307{
ea2deeec
MW
3308 { "zva", CPENS (3, C7, C4, 1), F_HASXT },
3309 { "ivac", CPENS (0, C7, C6, 1), F_HASXT },
3310 { "isw", CPENS (0, C7, C6, 2), F_HASXT },
3311 { "cvac", CPENS (3, C7, C10, 1), F_HASXT },
3312 { "csw", CPENS (0, C7, C10, 2), F_HASXT },
3313 { "cvau", CPENS (3, C7, C11, 1), F_HASXT },
d6bf7ce6 3314 { "cvap", CPENS (3, C7, C12, 1), F_HASXT | F_ARCHEXT },
ea2deeec
MW
3315 { "civac", CPENS (3, C7, C14, 1), F_HASXT },
3316 { "cisw", CPENS (0, C7, C14, 2), F_HASXT },
a06ea964
NC
3317 { 0, CPENS(0,0,0,0), 0 }
3318};
3319
3320const aarch64_sys_ins_reg aarch64_sys_regs_at[] =
3321{
ea2deeec
MW
3322 { "s1e1r", CPENS (0, C7, C8, 0), F_HASXT },
3323 { "s1e1w", CPENS (0, C7, C8, 1), F_HASXT },
3324 { "s1e0r", CPENS (0, C7, C8, 2), F_HASXT },
3325 { "s1e0w", CPENS (0, C7, C8, 3), F_HASXT },
3326 { "s12e1r", CPENS (4, C7, C8, 4), F_HASXT },
3327 { "s12e1w", CPENS (4, C7, C8, 5), F_HASXT },
3328 { "s12e0r", CPENS (4, C7, C8, 6), F_HASXT },
3329 { "s12e0w", CPENS (4, C7, C8, 7), F_HASXT },
3330 { "s1e2r", CPENS (4, C7, C8, 0), F_HASXT },
3331 { "s1e2w", CPENS (4, C7, C8, 1), F_HASXT },
3332 { "s1e3r", CPENS (6, C7, C8, 0), F_HASXT },
3333 { "s1e3w", CPENS (6, C7, C8, 1), F_HASXT },
22a5455c
MW
3334 { "s1e1rp", CPENS (0, C7, C9, 0), F_HASXT | F_ARCHEXT },
3335 { "s1e1wp", CPENS (0, C7, C9, 1), F_HASXT | F_ARCHEXT },
a06ea964
NC
3336 { 0, CPENS(0,0,0,0), 0 }
3337};
3338
3339const aarch64_sys_ins_reg aarch64_sys_regs_tlbi[] =
3340{
3341 { "vmalle1", CPENS(0,C8,C7,0), 0 },
ea2deeec
MW
3342 { "vae1", CPENS (0, C8, C7, 1), F_HASXT },
3343 { "aside1", CPENS (0, C8, C7, 2), F_HASXT },
3344 { "vaae1", CPENS (0, C8, C7, 3), F_HASXT },
a06ea964 3345 { "vmalle1is", CPENS(0,C8,C3,0), 0 },
ea2deeec
MW
3346 { "vae1is", CPENS (0, C8, C3, 1), F_HASXT },
3347 { "aside1is", CPENS (0, C8, C3, 2), F_HASXT },
3348 { "vaae1is", CPENS (0, C8, C3, 3), F_HASXT },
3349 { "ipas2e1is", CPENS (4, C8, C0, 1), F_HASXT },
3350 { "ipas2le1is",CPENS (4, C8, C0, 5), F_HASXT },
3351 { "ipas2e1", CPENS (4, C8, C4, 1), F_HASXT },
3352 { "ipas2le1", CPENS (4, C8, C4, 5), F_HASXT },
3353 { "vae2", CPENS (4, C8, C7, 1), F_HASXT },
3354 { "vae2is", CPENS (4, C8, C3, 1), F_HASXT },
a06ea964
NC
3355 { "vmalls12e1",CPENS(4,C8,C7,6), 0 },
3356 { "vmalls12e1is",CPENS(4,C8,C3,6), 0 },
ea2deeec
MW
3357 { "vae3", CPENS (6, C8, C7, 1), F_HASXT },
3358 { "vae3is", CPENS (6, C8, C3, 1), F_HASXT },
a06ea964
NC
3359 { "alle2", CPENS(4,C8,C7,0), 0 },
3360 { "alle2is", CPENS(4,C8,C3,0), 0 },
3361 { "alle1", CPENS(4,C8,C7,4), 0 },
3362 { "alle1is", CPENS(4,C8,C3,4), 0 },
3363 { "alle3", CPENS(6,C8,C7,0), 0 },
3364 { "alle3is", CPENS(6,C8,C3,0), 0 },
ea2deeec
MW
3365 { "vale1is", CPENS (0, C8, C3, 5), F_HASXT },
3366 { "vale2is", CPENS (4, C8, C3, 5), F_HASXT },
3367 { "vale3is", CPENS (6, C8, C3, 5), F_HASXT },
3368 { "vaale1is", CPENS (0, C8, C3, 7), F_HASXT },
3369 { "vale1", CPENS (0, C8, C7, 5), F_HASXT },
3370 { "vale2", CPENS (4, C8, C7, 5), F_HASXT },
3371 { "vale3", CPENS (6, C8, C7, 5), F_HASXT },
3372 { "vaale1", CPENS (0, C8, C7, 7), F_HASXT },
a06ea964
NC
3373 { 0, CPENS(0,0,0,0), 0 }
3374};
3375
ea2deeec
MW
3376bfd_boolean
3377aarch64_sys_ins_reg_has_xt (const aarch64_sys_ins_reg *sys_ins_reg)
3378{
3379 return (sys_ins_reg->flags & F_HASXT) != 0;
3380}
3381
d6bf7ce6
MW
3382extern bfd_boolean
3383aarch64_sys_ins_reg_supported_p (const aarch64_feature_set features,
3384 const aarch64_sys_ins_reg *reg)
3385{
3386 if (!(reg->flags & F_ARCHEXT))
3387 return TRUE;
3388
3389 /* DC CVAP. Values are from aarch64_sys_regs_dc. */
3390 if (reg->value == CPENS (3, C7, C12, 1)
3391 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
3392 return FALSE;
3393
63511907
MW
3394 /* AT S1E1RP, AT S1E1WP. Values are from aarch64_sys_regs_at. */
3395 if ((reg->value == CPENS (0, C7, C9, 0)
3396 || reg->value == CPENS (0, C7, C9, 1))
3397 && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
3398 return FALSE;
3399
d6bf7ce6
MW
3400 return TRUE;
3401}
3402
a06ea964
NC
3403#undef C0
3404#undef C1
3405#undef C2
3406#undef C3
3407#undef C4
3408#undef C5
3409#undef C6
3410#undef C7
3411#undef C8
3412#undef C9
3413#undef C10
3414#undef C11
3415#undef C12
3416#undef C13
3417#undef C14
3418#undef C15
3419
4bd13cde
NC
3420#define BIT(INSN,BT) (((INSN) >> (BT)) & 1)
3421#define BITS(INSN,HI,LO) (((INSN) >> (LO)) & ((1 << (((HI) - (LO)) + 1)) - 1))
3422
20f55f38 3423static bfd_boolean
4bd13cde
NC
3424verify_ldpsw (const struct aarch64_opcode * opcode ATTRIBUTE_UNUSED,
3425 const aarch64_insn insn)
3426{
3427 int t = BITS (insn, 4, 0);
3428 int n = BITS (insn, 9, 5);
3429 int t2 = BITS (insn, 14, 10);
3430
3431 if (BIT (insn, 23))
3432 {
3433 /* Write back enabled. */
3434 if ((t == n || t2 == n) && n != 31)
3435 return FALSE;
3436 }
3437
3438 if (BIT (insn, 22))
3439 {
3440 /* Load */
3441 if (t == t2)
3442 return FALSE;
3443 }
3444
3445 return TRUE;
3446}
3447
a06ea964
NC
3448/* Include the opcode description table as well as the operand description
3449 table. */
20f55f38 3450#define VERIFIER(x) verify_##x
a06ea964 3451#include "aarch64-tbl.h"
This page took 0.331879 seconds and 4 git commands to generate.