Coverage Report

Created: 2026-10-02 09:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/binutils-gdb/opcodes/aarch64-opc.c
Line
Count
Source
1
/* aarch64-opc.c -- AArch64 opcode support.
2
   Copyright (C) 2009-2026 Free Software Foundation, Inc.
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
#include "libiberty.h"
31
32
#include "aarch64-opc.h"
33
34
#ifdef DEBUG_AARCH64
35
int debug_dump = false;
36
#endif /* DEBUG_AARCH64 */
37
38
/* The enumeration strings associated with each value of a 5-bit SVE
39
   pattern operand.  A null entry indicates a reserved meaning.  */
40
const char *const aarch64_sve_pattern_array[32] = {
41
  /* 0-7.  */
42
  "pow2",
43
  "vl1",
44
  "vl2",
45
  "vl3",
46
  "vl4",
47
  "vl5",
48
  "vl6",
49
  "vl7",
50
  /* 8-15.  */
51
  "vl8",
52
  "vl16",
53
  "vl32",
54
  "vl64",
55
  "vl128",
56
  "vl256",
57
  0,
58
  0,
59
  /* 16-23.  */
60
  0,
61
  0,
62
  0,
63
  0,
64
  0,
65
  0,
66
  0,
67
  0,
68
  /* 24-31.  */
69
  0,
70
  0,
71
  0,
72
  0,
73
  0,
74
  "mul4",
75
  "mul3",
76
  "all"
77
};
78
79
/* The enumeration strings associated with each value of a 4-bit SVE
80
   prefetch operand.  A null entry indicates a reserved meaning.  */
81
const char *const aarch64_sve_prfop_array[16] = {
82
  /* 0-7.  */
83
  "pldl1keep",
84
  "pldl1strm",
85
  "pldl2keep",
86
  "pldl2strm",
87
  "pldl3keep",
88
  "pldl3strm",
89
  0,
90
  0,
91
  /* 8-15.  */
92
  "pstl1keep",
93
  "pstl1strm",
94
  "pstl2keep",
95
  "pstl2strm",
96
  "pstl3keep",
97
  "pstl3strm",
98
  0,
99
  0
100
};
101
102
/* The enumeration strings associated with each value of a 6-bit RPRFM
103
   operation.  */
104
const char *const aarch64_rprfmop_array[64] = {
105
  "pldkeep",
106
  "pstkeep",
107
  0,
108
  0,
109
  "pldstrm",
110
  "pststrm"
111
};
112
113
/* Vector length multiples for a predicate-as-counter operand.  Used in things
114
   like AARCH64_OPND_SME_VLxN_10.  */
115
const char *const aarch64_sme_vlxn_array[2] = {
116
  "vlx2",
117
  "vlx4"
118
};
119
120
/* Values accepted by the brb alias.  */
121
const char *const aarch64_brbop_array[] = {
122
  "iall",
123
  "inj",
124
};
125
126
/* Helper functions to determine which operand to be used to encode/decode
127
   the size:Q fields for AdvSIMD instructions.  */
128
129
static inline bool
130
vector_qualifier_p (enum aarch64_opnd_qualifier qualifier)
131
839k
{
132
839k
  return (qualifier >= AARCH64_OPND_QLF_V_8B
133
671k
    && qualifier <= AARCH64_OPND_QLF_V_1Q);
134
839k
}
135
136
static inline bool
137
fp_qualifier_p (enum aarch64_opnd_qualifier qualifier)
138
1.29k
{
139
1.29k
  return (qualifier >= AARCH64_OPND_QLF_S_B
140
1.29k
    && qualifier <= AARCH64_OPND_QLF_S_Q);
141
1.29k
}
142
143
enum data_pattern
144
{
145
  DP_UNKNOWN,
146
  DP_VECTOR_3SAME,
147
  DP_VECTOR_LONG,
148
  DP_VECTOR_WIDE,
149
  DP_VECTOR_ACROSS_LANES,
150
};
151
152
static const char significant_operand_index [] =
153
{
154
  0,  /* DP_UNKNOWN, by default using operand 0.  */
155
  0,  /* DP_VECTOR_3SAME */
156
  1,  /* DP_VECTOR_LONG */
157
  2,  /* DP_VECTOR_WIDE */
158
  1,  /* DP_VECTOR_ACROSS_LANES */
159
};
160
161
/* Given a sequence of qualifiers in QUALIFIERS, determine and return
162
   the data pattern.
163
   N.B. QUALIFIERS is a possible sequence of qualifiers each of which
164
   corresponds to one of a sequence of operands.  */
165
166
static enum data_pattern
167
get_data_pattern (const aarch64_opnd_qualifier_seq_t qualifiers)
168
364k
{
169
364k
  if (vector_qualifier_p (qualifiers[0]))
170
362k
    {
171
      /* e.g. v.4s, v.4s, v.4s
172
     or v.4h, v.4h, v.h[3].  */
173
362k
      if (qualifiers[0] == qualifiers[1]
174
174k
    && vector_qualifier_p (qualifiers[2])
175
125k
    && (aarch64_get_qualifier_esize (qualifiers[0])
176
125k
        == aarch64_get_qualifier_esize (qualifiers[2])))
177
118k
  return DP_VECTOR_3SAME;
178
      /* e.g. v.8h, v.8b, v.8b.
179
           or v.4s, v.4h, v.h[2].
180
     or v.8h, v.16b.  */
181
244k
      if (vector_qualifier_p (qualifiers[1])
182
172k
    && aarch64_get_qualifier_esize (qualifiers[0]) != 0
183
172k
    && (aarch64_get_qualifier_esize (qualifiers[0])
184
172k
        == aarch64_get_qualifier_esize (qualifiers[1]) << 1))
185
61.2k
  return DP_VECTOR_LONG;
186
      /* e.g. v.8h, v.8h, v.8b.  */
187
182k
      if (qualifiers[0] == qualifiers[1]
188
55.4k
    && vector_qualifier_p (qualifiers[2])
189
6.50k
    && aarch64_get_qualifier_esize (qualifiers[0]) != 0
190
6.50k
    && (aarch64_get_qualifier_esize (qualifiers[0])
191
6.50k
        == aarch64_get_qualifier_esize (qualifiers[2]) << 1))
192
6.50k
  return DP_VECTOR_WIDE;
193
182k
    }
194
1.29k
  else if (fp_qualifier_p (qualifiers[0]))
195
1.29k
    {
196
      /* e.g. SADDLV <V><d>, <Vn>.<T>.  */
197
1.29k
      if (vector_qualifier_p (qualifiers[1])
198
1.11k
    && (qualifiers[2] == AARCH64_OPND_QLF_UNUSED))
199
1.11k
  return DP_VECTOR_ACROSS_LANES;
200
1.29k
    }
201
202
176k
  return DP_UNKNOWN;
203
364k
}
204
205
/* Select the operand to do the encoding/decoding of the 'size:Q' fields in
206
   the AdvSIMD instructions.  */
207
/* N.B. it is possible to do some optimization that doesn't call
208
   get_data_pattern each time when we need to select an operand.  We can
209
   either buffer the caculated the result or statically generate the data,
210
   however, it is not obvious that the optimization will bring significant
211
   benefit.  */
212
213
int
214
aarch64_select_operand_for_sizeq_field_coding (const aarch64_opcode *opcode)
215
364k
{
216
364k
  return
217
364k
    significant_operand_index [get_data_pattern (opcode->qualifiers_list[0])];
218
364k
}
219

220
enum aarch64_operand_class
221
aarch64_get_operand_class (enum aarch64_opnd type)
222
3.03M
{
223
3.03M
  return aarch64_operands[type].op_class;
224
3.03M
}
225
226
const char *
227
aarch64_get_operand_name (enum aarch64_opnd type)
228
0
{
229
0
  return aarch64_operands[type].name;
230
0
}
231
232
/* Get operand description string.
233
   This is usually for the diagnosis purpose.  */
234
const char *
235
aarch64_get_operand_desc (enum aarch64_opnd type)
236
0
{
237
0
  return aarch64_operands[type].desc;
238
0
}
239
240
/* Table of all conditional affixes.  */
241
const aarch64_cond aarch64_conds[16] =
242
{
243
  {{"eq", "none"}, 0x0},
244
  {{"ne", "any"}, 0x1},
245
  {{"cs", "hs", "nlast"}, 0x2},
246
  {{"cc", "lo", "ul", "last"}, 0x3},
247
  {{"mi", "first"}, 0x4},
248
  {{"pl", "nfrst"}, 0x5},
249
  {{"vs"}, 0x6},
250
  {{"vc"}, 0x7},
251
  {{"hi", "pmore"}, 0x8},
252
  {{"ls", "plast"}, 0x9},
253
  {{"ge", "tcont"}, 0xa},
254
  {{"lt", "tstop"}, 0xb},
255
  {{"gt"}, 0xc},
256
  {{"le"}, 0xd},
257
  {{"al"}, 0xe},
258
  {{"nv"}, 0xf},
259
};
260
261
const aarch64_cond *
262
get_cond_from_value (aarch64_insn value)
263
71.6k
{
264
71.6k
  assert (value < 16);
265
71.6k
  return &aarch64_conds[(unsigned int) value];
266
71.6k
}
267
268
const aarch64_cond *
269
get_inverted_cond (const aarch64_cond *cond)
270
619
{
271
619
  return &aarch64_conds[cond->value ^ 0x1];
272
619
}
273
274
/* Table describing the operand extension/shifting operators; indexed by
275
   enum aarch64_modifier_kind.
276
277
   The value column provides the most common values for encoding modifiers,
278
   which enables table-driven encoding/decoding for the modifiers.  */
279
const struct aarch64_name_value_pair aarch64_operand_modifiers [] =
280
{
281
    {"none", 0x0},
282
    {"msl",  0x0},
283
    {"ror",  0x3},
284
    {"asr",  0x2},
285
    {"lsr",  0x1},
286
    {"lsl",  0x0},
287
    {"uxtb", 0x0},
288
    {"uxth", 0x1},
289
    {"uxtw", 0x2},
290
    {"uxtx", 0x3},
291
    {"sxtb", 0x4},
292
    {"sxth", 0x5},
293
    {"sxtw", 0x6},
294
    {"sxtx", 0x7},
295
    {"mul", 0x0},
296
    {"mul vl", 0x0},
297
    {NULL, 0},
298
};
299
300
enum aarch64_modifier_kind
301
aarch64_get_operand_modifier (const struct aarch64_name_value_pair *desc)
302
0
{
303
0
  return desc - aarch64_operand_modifiers;
304
0
}
305
306
aarch64_insn
307
aarch64_get_operand_modifier_value (enum aarch64_modifier_kind kind)
308
0
{
309
0
  return aarch64_operand_modifiers[kind].value;
310
0
}
311
312
enum aarch64_modifier_kind
313
aarch64_get_operand_modifier_from_value (aarch64_insn value,
314
           bool extend_p)
315
704k
{
316
704k
  if (extend_p)
317
125k
    return AARCH64_MOD_UXTB + value;
318
578k
  else
319
578k
    return AARCH64_MOD_LSL - value;
320
704k
}
321
322
bool
323
aarch64_extend_operator_p (enum aarch64_modifier_kind kind)
324
61.0k
{
325
61.0k
  return kind > AARCH64_MOD_LSL && kind <= AARCH64_MOD_SXTX;
326
61.0k
}
327
328
static inline bool
329
aarch64_shift_operator_p (enum aarch64_modifier_kind kind)
330
552k
{
331
552k
  return kind >= AARCH64_MOD_ROR && kind <= AARCH64_MOD_LSL;
332
552k
}
333
334
const struct aarch64_name_value_pair aarch64_barrier_options[16] =
335
{
336
    { "#0x00", 0x0 },
337
    { "oshld", 0x1 },
338
    { "oshst", 0x2 },
339
    { "osh",   0x3 },
340
    { "#0x04", 0x4 },
341
    { "nshld", 0x5 },
342
    { "nshst", 0x6 },
343
    { "nsh",   0x7 },
344
    { "#0x08", 0x8 },
345
    { "ishld", 0x9 },
346
    { "ishst", 0xa },
347
    { "ish",   0xb },
348
    { "#0x0c", 0xc },
349
    { "ld",    0xd },
350
    { "st",    0xe },
351
    { "sy",    0xf },
352
};
353
354
const struct aarch64_name_value_pair aarch64_barrier_dsb_nxs_options[4] =
355
{                       /*  CRm<3:2>  #imm  */
356
    { "oshnxs", 16 },    /*    00       16   */
357
    { "nshnxs", 20 },    /*    01       20   */
358
    { "ishnxs", 24 },    /*    10       24   */
359
    { "synxs",  28 },    /*    11       28   */
360
};
361
362
/* Table describing the operands supported by the aliases of the HINT
363
   instruction.
364
365
   The name column is the operand that is accepted for the alias.  The value
366
   column is the hint number of the alias.  The list of operands is terminated
367
   by NULL in the name column.  */
368
369
const struct aarch64_name_value_pair aarch64_hint_options[] =
370
{
371
  /* BTI.  This is also the F_DEFAULT entry for AARCH64_OPND_BTI_TARGET.
372
     BTI R and SHUH must be the first and second entries respectively
373
     so that F_DEFAULT refers to the correct table entries.  */
374
  { "r",  HINT_OPD_R },   /* BTI R.  */
375
  { "",   HINT_OPD_NPHINT}, /* SHUH. */
376
  { "csync",  HINT_OPD_CSYNC }, /* PSB CSYNC.  */
377
  { "dsync",  HINT_OPD_DSYNC }, /* GCSB DSYNC.  */
378
  { "c",  HINT_OPD_C },   /* BTI C.  */
379
  { "j",  HINT_OPD_J },   /* BTI J.  */
380
  { "jc", HINT_OPD_JC },    /* BTI JC.  */
381
  { "keep", HINT_OPD_KEEP },  /* STSHH KEEP  */
382
  { "strm", HINT_OPD_STRM },  /* STSHH STRM  */
383
  { "ph", HINT_OPD_PHINT }, /* SHUH PH.  */
384
  { NULL, HINT_OPD_NULL },
385
};
386
387
/* op -> op:       load = 0 instruction = 1 store = 2
388
   l  -> level:    1-3
389
   t  -> temporal: temporal (retained) = 0 non-temporal (streaming) = 1   */
390
#define B(op,l,t) (((op) << 3) | (((l) - 1) << 1) | (t))
391
const struct aarch64_name_value_pair aarch64_prfops[32] =
392
{
393
  { "pldl1keep", B(0, 1, 0) },
394
  { "pldl1strm", B(0, 1, 1) },
395
  { "pldl2keep", B(0, 2, 0) },
396
  { "pldl2strm", B(0, 2, 1) },
397
  { "pldl3keep", B(0, 3, 0) },
398
  { "pldl3strm", B(0, 3, 1) },
399
  { "pldslckeep", B(0, 4, 0) },
400
  { "pldslcstrm", B(0, 4, 1) },
401
  { "plil1keep", B(1, 1, 0) },
402
  { "plil1strm", B(1, 1, 1) },
403
  { "plil2keep", B(1, 2, 0) },
404
  { "plil2strm", B(1, 2, 1) },
405
  { "plil3keep", B(1, 3, 0) },
406
  { "plil3strm", B(1, 3, 1) },
407
  { "plislckeep", B(1, 4, 0) },
408
  { "plislcstrm", B(1, 4, 1) },
409
  { "pstl1keep", B(2, 1, 0) },
410
  { "pstl1strm", B(2, 1, 1) },
411
  { "pstl2keep", B(2, 2, 0) },
412
  { "pstl2strm", B(2, 2, 1) },
413
  { "pstl3keep", B(2, 3, 0) },
414
  { "pstl3strm", B(2, 3, 1) },
415
  { "pstslckeep", B(2, 4, 0) },
416
  { "pstslcstrm", B(2, 4, 1) },
417
  { "ir", B(3, 1, 0) },
418
  { NULL, 0x19 },
419
  { NULL, 0x1a },
420
  { NULL, 0x1b },
421
  { NULL, 0x1c },
422
  { NULL, 0x1d },
423
  { NULL, 0x1e },
424
  { NULL, 0x1f },
425
};
426
#undef B
427

428
/* Utilities on value constraint.  */
429
430
static inline bool
431
value_in_range_p (int64_t value, int64_t low, int64_t high)
432
3.16M
{
433
3.16M
  return (low <= value) && (value <= high);
434
3.16M
}
435
436
/* Return true if VALUE is a multiple of ALIGN.  */
437
static inline bool
438
value_aligned_p (int64_t value, int align)
439
2.12M
{
440
2.12M
  return (value % align) == 0;
441
2.12M
}
442
443
/* A signed value fits in a field.  */
444
static inline bool
445
value_fit_signed_field_p (int64_t value, unsigned width)
446
1.39M
{
447
1.39M
  assert (width < 32);
448
1.39M
  if (width < sizeof (value) * 8)
449
1.39M
    {
450
1.39M
      int64_t lim = (uint64_t) 1 << (width - 1);
451
1.39M
      if (value >= -lim && value < lim)
452
1.39M
  return true;
453
1.39M
    }
454
0
  return false;
455
1.39M
}
456
457
/* An unsigned value fits in a field.  */
458
static inline bool
459
value_fit_unsigned_field_p (int64_t value, unsigned width)
460
2.46M
{
461
2.46M
  assert (width < 32);
462
2.46M
  if (width < sizeof (value) * 8)
463
2.46M
    {
464
2.46M
      int64_t lim = (uint64_t) 1 << width;
465
2.46M
      if (value >= 0 && value < lim)
466
2.46M
  return true;
467
2.46M
    }
468
0
  return false;
469
2.46M
}
470
471
/* Return true if OPERAND is SP or WSP.  */
472
bool
473
aarch64_stack_pointer_p (const aarch64_opnd_info *operand)
474
190k
{
475
190k
  return ((aarch64_get_operand_class (operand->type)
476
190k
     == AARCH64_OPND_CLASS_INT_REG)
477
190k
    && operand_maybe_stack_pointer (aarch64_operands + operand->type)
478
120k
    && operand->reg.regno == 31);
479
190k
}
480
481
/* Return 1 if OPERAND is XZR or WZP.  */
482
int
483
aarch64_zero_register_p (const aarch64_opnd_info *operand)
484
0
{
485
0
  return ((aarch64_get_operand_class (operand->type)
486
0
     == AARCH64_OPND_CLASS_INT_REG)
487
0
    && !operand_maybe_stack_pointer (aarch64_operands + operand->type)
488
0
    && operand->reg.regno == 31);
489
0
}
490
491
enum operand_qualifier_kind
492
{
493
  OQK_NIL,
494
  OQK_OPD_VARIANT,
495
  OQK_VALUE_IN_RANGE,
496
  OQK_MISC,
497
};
498
499
/* Operand qualifier description.  */
500
struct operand_qualifier_data
501
{
502
  /* The usage of the three data fields depends on the qualifier kind.  */
503
  int data0;
504
  int data1;
505
  int data2;
506
  /* Description.  */
507
  const char *desc;
508
  /* Kind.  */
509
  enum operand_qualifier_kind kind;
510
};
511
512
/* Indexed by the operand qualifier enumerators.  */
513
static const struct operand_qualifier_data aarch64_opnd_qualifiers[] =
514
{
515
  {0, 0, 0, "UNUSED", OQK_NIL},
516
  {0, 0, 0, "NIL", OQK_NIL},
517
  {0, 0, 0, "UNKNOWN", OQK_NIL},
518
519
  /* Operand variant qualifiers.
520
     First 3 fields:
521
     element size, number of elements and common value for encoding.  */
522
523
  {4, 1, 0x0, "w", OQK_OPD_VARIANT},
524
  {8, 1, 0x1, "x", OQK_OPD_VARIANT},
525
526
  {1, 1, 0x0, "b", OQK_OPD_VARIANT},
527
  {2, 1, 0x1, "h", OQK_OPD_VARIANT},
528
  {4, 1, 0x2, "s", OQK_OPD_VARIANT},
529
  {8, 1, 0x3, "d", OQK_OPD_VARIANT},
530
  {16, 1, 0x4, "q", OQK_OPD_VARIANT},
531
  {2, 1, 0x0, "2b", OQK_OPD_VARIANT},
532
  {4, 1, 0x0, "4b", OQK_OPD_VARIANT},
533
  {4, 1, 0x0, "2h", OQK_OPD_VARIANT},
534
535
  {1, 4, 0x0, "4b", OQK_OPD_VARIANT},
536
  {1, 8, 0x0, "8b", OQK_OPD_VARIANT},
537
  {1, 16, 0x1, "16b", OQK_OPD_VARIANT},
538
  {2, 2, 0x0, "2h", OQK_OPD_VARIANT},
539
  {2, 4, 0x2, "4h", OQK_OPD_VARIANT},
540
  {2, 8, 0x3, "8h", OQK_OPD_VARIANT},
541
  {4, 2, 0x4, "2s", OQK_OPD_VARIANT},
542
  {4, 4, 0x5, "4s", OQK_OPD_VARIANT},
543
  {8, 1, 0x6, "1d", OQK_OPD_VARIANT},
544
  {8, 2, 0x7, "2d", OQK_OPD_VARIANT},
545
  {16, 1, 0x8, "1q", OQK_OPD_VARIANT},
546
547
  {0, 0, 0, "z", OQK_OPD_VARIANT},
548
  {0, 0, 0, "m", OQK_OPD_VARIANT},
549
550
  /* Qualifier for scaled immediate for Tag granule (stg,st2g,etc).  */
551
  {16, 0, 0, "tag", OQK_OPD_VARIANT},
552
553
  /* Qualifiers constraining the value range.
554
     First 3 fields:
555
     Lower bound, higher bound, unused.  */
556
557
  {0, 15, 0, "CR",       OQK_VALUE_IN_RANGE},
558
  {0,  7, 0, "imm_0_7" , OQK_VALUE_IN_RANGE},
559
  {0, 15, 0, "imm_0_15", OQK_VALUE_IN_RANGE},
560
  {0, 31, 0, "imm_0_31", OQK_VALUE_IN_RANGE},
561
  {0, 63, 0, "imm_0_63", OQK_VALUE_IN_RANGE},
562
  {1, 32, 0, "imm_1_32", OQK_VALUE_IN_RANGE},
563
  {1, 64, 0, "imm_1_64", OQK_VALUE_IN_RANGE},
564
565
  /* Qualifiers for miscellaneous purpose.
566
     First 3 fields:
567
     unused, unused and unused.  */
568
569
  {0, 0, 0, "lsl", 0},
570
  {0, 0, 0, "msl", 0},
571
572
  {0, 0, 0, "retrieving", 0},
573
574
  /* This shouldn't ever be used.  */
575
  {0, 0, 0, "ERR", OQK_NIL},
576
};
577
578
static inline bool
579
operand_variant_qualifier_p (aarch64_opnd_qualifier_t qualifier)
580
12.5M
{
581
12.5M
  return aarch64_opnd_qualifiers[qualifier].kind == OQK_OPD_VARIANT;
582
12.5M
}
583
584
static inline bool
585
qualifier_value_in_range_constraint_p (aarch64_opnd_qualifier_t qualifier)
586
4.56M
{
587
4.56M
  return aarch64_opnd_qualifiers[qualifier].kind == OQK_VALUE_IN_RANGE;
588
4.56M
}
589
590
const char*
591
aarch64_get_qualifier_name (aarch64_opnd_qualifier_t qualifier)
592
4.84M
{
593
4.84M
  return aarch64_opnd_qualifiers[qualifier].desc;
594
4.84M
}
595
596
/* Given an operand qualifier, return the expected data element size
597
   of a qualified operand.  */
598
unsigned char
599
aarch64_get_qualifier_esize (aarch64_opnd_qualifier_t qualifier)
600
8.99M
{
601
8.99M
  assert (operand_variant_qualifier_p (qualifier));
602
8.99M
  return aarch64_opnd_qualifiers[qualifier].data0;
603
8.99M
}
604
605
unsigned char
606
aarch64_get_qualifier_nelem (aarch64_opnd_qualifier_t qualifier)
607
113k
{
608
113k
  assert (operand_variant_qualifier_p (qualifier));
609
113k
  return aarch64_opnd_qualifiers[qualifier].data1;
610
113k
}
611
612
aarch64_insn
613
aarch64_get_qualifier_standard_value (aarch64_opnd_qualifier_t qualifier)
614
3.45M
{
615
3.45M
  assert (operand_variant_qualifier_p (qualifier));
616
3.45M
  return aarch64_opnd_qualifiers[qualifier].data2;
617
3.45M
}
618
619
static int
620
get_lower_bound (aarch64_opnd_qualifier_t qualifier)
621
507k
{
622
507k
  assert (qualifier_value_in_range_constraint_p (qualifier));
623
507k
  return aarch64_opnd_qualifiers[qualifier].data0;
624
507k
}
625
626
static int
627
get_upper_bound (aarch64_opnd_qualifier_t qualifier)
628
542k
{
629
542k
  assert (qualifier_value_in_range_constraint_p (qualifier));
630
542k
  return aarch64_opnd_qualifiers[qualifier].data1;
631
542k
}
632
633
#ifdef DEBUG_AARCH64
634
void
635
aarch64_verbose (const char *str, ...)
636
{
637
  va_list ap;
638
  va_start (ap, str);
639
  printf ("#### ");
640
  vprintf (str, ap);
641
  printf ("\n");
642
  va_end (ap);
643
}
644
645
static inline void
646
dump_qualifier_sequence (const aarch64_opnd_qualifier_t *qualifier)
647
{
648
  int i;
649
  printf ("#### \t");
650
  for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i, ++qualifier)
651
    printf ("%s,", aarch64_get_qualifier_name (*qualifier));
652
  printf ("\n");
653
}
654
655
static void
656
dump_match_qualifiers (const struct aarch64_opnd_info *opnd,
657
           const aarch64_opnd_qualifier_t *qualifier)
658
{
659
  int i;
660
  aarch64_opnd_qualifier_t curr[AARCH64_MAX_OPND_NUM];
661
662
  aarch64_verbose ("dump_match_qualifiers:");
663
  for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
664
    curr[i] = opnd[i].qualifier;
665
  dump_qualifier_sequence (curr);
666
  aarch64_verbose ("against");
667
  dump_qualifier_sequence (qualifier);
668
}
669
#endif /* DEBUG_AARCH64 */
670
671
/* This function checks if the given instruction INSN is a destructive
672
   instruction based on the usage of the registers.  It does not recognize
673
   unary destructive instructions.  */
674
bool
675
aarch64_is_destructive_by_operands (const aarch64_opcode *opcode)
676
572
{
677
572
  int i = 0;
678
572
  const enum aarch64_opnd *opnds = opcode->operands;
679
680
572
  if (opnds[0] == AARCH64_OPND_NIL)
681
0
    return false;
682
683
1.64k
  while (opnds[++i] != AARCH64_OPND_NIL)
684
1.39k
    if (opnds[i] == opnds[0])
685
322
      return true;
686
687
250
  return false;
688
572
}
689
690
/* TODO improve this, we can have an extra field at the runtime to
691
   store the number of operands rather than calculating it every time.  */
692
693
int
694
aarch64_num_of_operands (const aarch64_opcode *opcode)
695
10.4M
{
696
10.4M
  int i = 0;
697
10.4M
  const enum aarch64_opnd *opnds = opcode->operands;
698
36.1M
  while (opnds[i++] != AARCH64_OPND_NIL)
699
25.6M
    ;
700
10.4M
  --i;
701
10.4M
  assert (i >= 0 && i <= AARCH64_MAX_OPND_NUM);
702
10.4M
  return i;
703
10.4M
}
704
705
/* Find the best matched qualifier sequence in *QUALIFIERS_LIST for INST.
706
   If succeeds, fill the found sequence in *RET, return 1; otherwise return 0.
707
708
   Store the smallest number of non-matching qualifiers in *INVALID_COUNT.
709
   This is always 0 if the function succeeds.
710
711
   N.B. on the entry, it is very likely that only some operands in *INST
712
   have had their qualifiers been established.
713
714
   If STOP_AT is not -1, the function will only try to match
715
   the qualifier sequence for operands before and including the operand
716
   of index STOP_AT; and on success *RET will only be filled with the first
717
   (STOP_AT+1) qualifiers.
718
719
   A couple examples of the matching algorithm:
720
721
   X,W,NIL should match
722
   X,W,NIL
723
724
   NIL,NIL should match
725
   X  ,NIL
726
727
   Apart from serving the main encoding routine, this can also be called
728
   during or after the operand decoding.  */
729
730
int
731
aarch64_find_best_match (const aarch64_inst *inst,
732
       const aarch64_opnd_qualifier_seq_t *qualifiers_list,
733
       int stop_at, aarch64_opnd_qualifier_t *ret,
734
       int *invalid_count)
735
9.43M
{
736
9.43M
  int i, num_opnds, invalid, min_invalid;
737
9.43M
  const aarch64_opnd_qualifier_t *qualifiers;
738
739
9.43M
  num_opnds = aarch64_num_of_operands (inst->opcode);
740
9.43M
  if (num_opnds == 0)
741
95
    {
742
95
      DEBUG_TRACE ("SUCCEED: no operand");
743
95
      *invalid_count = 0;
744
95
      return 1;
745
95
    }
746
747
9.43M
  if (stop_at < 0 || stop_at >= num_opnds)
748
8.24M
    stop_at = num_opnds - 1;
749
750
  /* For each pattern.  */
751
9.43M
  min_invalid = num_opnds;
752
13.0M
  for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i, ++qualifiers_list)
753
13.0M
    {
754
13.0M
      int j;
755
13.0M
      qualifiers = *qualifiers_list;
756
757
      /* Start as positive.  */
758
13.0M
      invalid = 0;
759
760
13.0M
      DEBUG_TRACE ("%d", i);
761
#ifdef DEBUG_AARCH64
762
      if (debug_dump)
763
  dump_match_qualifiers (inst->operands, qualifiers);
764
#endif
765
766
      /* The first entry should be taken literally, even if it's an empty
767
   qualifier sequence.  In other positions an empty sequence acts as a
768
   terminator.  */
769
13.0M
      if (i > 0 && empty_qualifier_sequence_p (qualifiers))
770
72.0k
  break;
771
772
44.9M
      for (j = 0; j < num_opnds && j <= stop_at; ++j, ++qualifiers)
773
32.0M
  if (inst->operands[j].qualifier != *qualifiers
774
21.7M
       && inst->operands[j].qualifier != AARCH64_OPND_QLF_UNKNOWN)
775
5.07M
    invalid += 1;
776
777
12.9M
      if (min_invalid > invalid)
778
11.4M
  min_invalid = invalid;
779
780
      /* Qualifiers established.  */
781
12.9M
      if (min_invalid == 0)
782
9.35M
  break;
783
12.9M
    }
784
785
9.43M
  *invalid_count = min_invalid;
786
9.43M
  if (min_invalid == 0)
787
9.35M
    {
788
      /* Fill the result in *RET.  */
789
9.35M
      int j;
790
9.35M
      qualifiers = *qualifiers_list;
791
792
9.35M
      DEBUG_TRACE ("complete qualifiers using list %d", i);
793
#ifdef DEBUG_AARCH64
794
      if (debug_dump)
795
  dump_qualifier_sequence (qualifiers);
796
#endif
797
798
31.5M
      for (j = 0; j <= stop_at; ++j, ++qualifiers)
799
22.2M
  ret[j] = *qualifiers;
800
52.6M
      for (; j < AARCH64_MAX_OPND_NUM; ++j)
801
43.3M
  ret[j] = AARCH64_OPND_QLF_UNKNOWN;
802
803
9.35M
      DEBUG_TRACE ("SUCCESS");
804
9.35M
      return 1;
805
9.35M
    }
806
807
72.0k
  DEBUG_TRACE ("FAIL");
808
72.0k
  return 0;
809
9.43M
}
810
811
/* Operand qualifier matching and resolving.
812
813
   Return 1 if the operand qualifier(s) in *INST match one of the qualifier
814
   sequences in INST->OPCODE->qualifiers_list; otherwise return 0.
815
816
   Store the smallest number of non-matching qualifiers in *INVALID_COUNT.
817
   This is always 0 if the function succeeds.
818
819
   if UPDATE_P, update the qualifier(s) in *INST after the matching
820
   succeeds.  */
821
822
static int
823
match_operands_qualifier (aarch64_inst *inst, bool update_p,
824
        int *invalid_count)
825
8.24M
{
826
8.24M
  int i;
827
8.24M
  aarch64_opnd_qualifier_seq_t qualifiers;
828
829
8.24M
  if (!aarch64_find_best_match (inst, inst->opcode->qualifiers_list, -1,
830
8.24M
        qualifiers, invalid_count))
831
43.7k
    {
832
43.7k
      DEBUG_TRACE ("matching FAIL");
833
43.7k
      return 0;
834
43.7k
    }
835
836
  /* Update the qualifiers.  */
837
8.19M
  if (update_p)
838
27.3M
    for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
839
27.3M
      {
840
27.3M
  if (inst->opcode->operands[i] == AARCH64_OPND_NIL)
841
8.19M
    break;
842
19.1M
  DEBUG_TRACE_IF (inst->operands[i].qualifier != qualifiers[i],
843
19.1M
      "update %s with %s for operand %d",
844
19.1M
      aarch64_get_qualifier_name (inst->operands[i].qualifier),
845
19.1M
      aarch64_get_qualifier_name (qualifiers[i]), i);
846
19.1M
  inst->operands[i].qualifier = qualifiers[i];
847
19.1M
      }
848
849
8.19M
  DEBUG_TRACE ("matching SUCCESS");
850
8.19M
  return 1;
851
8.24M
}
852
853
/* Return TRUE if VALUE is a wide constant that can be moved into a general
854
   register by MOVZ.
855
856
   IS32 indicates whether value is a 32-bit immediate or not.
857
   If SHIFT_AMOUNT is not NULL, on the return of TRUE, the logical left shift
858
   amount will be returned in *SHIFT_AMOUNT.  */
859
860
bool
861
aarch64_wide_constant_p (uint64_t value, int is32, unsigned int *shift_amount)
862
97.2k
{
863
97.2k
  int amount;
864
865
97.2k
  DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 ")", value, value);
866
867
97.2k
  if (is32)
868
17.0k
    {
869
      /* Allow all zeros or all ones in top 32-bits, so that
870
   32-bit constant expressions like ~0x80000000 are
871
   permitted.  */
872
17.0k
      if (value >> 32 != 0 && value >> 32 != 0xffffffff)
873
  /* Immediate out of range.  */
874
0
  return false;
875
17.0k
      value &= 0xffffffff;
876
17.0k
    }
877
878
  /* first, try movz then movn */
879
97.2k
  amount = -1;
880
97.2k
  if ((value & ((uint64_t) 0xffff << 0)) == value)
881
23.6k
    amount = 0;
882
73.5k
  else if ((value & ((uint64_t) 0xffff << 16)) == value)
883
11.8k
    amount = 16;
884
61.6k
  else if (!is32 && (value & ((uint64_t) 0xffff << 32)) == value)
885
25.1k
    amount = 32;
886
36.5k
  else if (!is32 && (value & ((uint64_t) 0xffff << 48)) == value)
887
5.30k
    amount = 48;
888
889
97.2k
  if (amount == -1)
890
31.2k
    {
891
31.2k
      DEBUG_TRACE ("exit false with 0x%" PRIx64 "(%" PRIi64 ")", value, value);
892
31.2k
      return false;
893
31.2k
    }
894
895
65.9k
  if (shift_amount != NULL)
896
0
    *shift_amount = amount;
897
898
65.9k
  DEBUG_TRACE ("exit true with amount %d", amount);
899
900
65.9k
  return true;
901
97.2k
}
902
903
/* Build the accepted values for immediate logical SIMD instructions.
904
905
   The standard encodings of the immediate value are:
906
     N      imms     immr         SIMD size  R             S
907
     1      ssssss   rrrrrr       64      UInt(rrrrrr)  UInt(ssssss)
908
     0      0sssss   0rrrrr       32      UInt(rrrrr)   UInt(sssss)
909
     0      10ssss   00rrrr       16      UInt(rrrr)    UInt(ssss)
910
     0      110sss   000rrr       8       UInt(rrr)     UInt(sss)
911
     0      1110ss   0000rr       4       UInt(rr)      UInt(ss)
912
     0      11110s   00000r       2       UInt(r)       UInt(s)
913
   where all-ones value of S is reserved.
914
915
   Let's call E the SIMD size.
916
917
   The immediate value is: S+1 bits '1' rotated to the right by R.
918
919
   The total of valid encodings is 64*63 + 32*31 + ... + 2*1 = 5334
920
   (remember S != E - 1).  */
921
922
355k
#define TOTAL_IMM_NB  5334
923
924
typedef struct
925
{
926
  uint64_t imm;
927
  aarch64_insn encoding;
928
} simd_imm_encoding;
929
930
static simd_imm_encoding simd_immediates[TOTAL_IMM_NB];
931
932
static int
933
simd_imm_encoding_cmp(const void *i1, const void *i2)
934
4.18M
{
935
4.18M
  const simd_imm_encoding *imm1 = (const simd_imm_encoding *)i1;
936
4.18M
  const simd_imm_encoding *imm2 = (const simd_imm_encoding *)i2;
937
938
4.18M
  if (imm1->imm < imm2->imm)
939
2.09M
    return -1;
940
2.09M
  if (imm1->imm > imm2->imm)
941
1.73M
    return +1;
942
355k
  return 0;
943
2.09M
}
944
945
/* immediate bitfield standard encoding
946
   imm13<12> imm13<5:0> imm13<11:6> SIMD size R      S
947
   1         ssssss     rrrrrr      64        rrrrrr ssssss
948
   0         0sssss     0rrrrr      32        rrrrr  sssss
949
   0         10ssss     00rrrr      16        rrrr   ssss
950
   0         110sss     000rrr      8         rrr    sss
951
   0         1110ss     0000rr      4         rr     ss
952
   0         11110s     00000r      2         r      s  */
953
static inline int
954
encode_immediate_bitfield (int is64, uint32_t s, uint32_t r)
955
10.6k
{
956
10.6k
  return (is64 << 12) | (r << 6) | s;
957
10.6k
}
958
959
static void
960
build_immediate_table (void)
961
2
{
962
2
  uint32_t log_e, e, s, r, s_mask;
963
2
  uint64_t mask, imm;
964
2
  int nb_imms;
965
2
  int is64;
966
967
2
  nb_imms = 0;
968
14
  for (log_e = 1; log_e <= 6; log_e++)
969
12
    {
970
      /* Get element size.  */
971
12
      e = 1u << log_e;
972
12
      if (log_e == 6)
973
2
  {
974
2
    is64 = 1;
975
2
    mask = 0xffffffffffffffffull;
976
2
    s_mask = 0;
977
2
  }
978
10
      else
979
10
  {
980
10
    is64 = 0;
981
10
    mask = (1ull << e) - 1;
982
    /* log_e  s_mask
983
       1     ((1 << 4) - 1) << 2 = 111100
984
       2     ((1 << 3) - 1) << 3 = 111000
985
       3     ((1 << 2) - 1) << 4 = 110000
986
       4     ((1 << 1) - 1) << 5 = 100000
987
       5     ((1 << 0) - 1) << 6 = 000000  */
988
10
    s_mask = ((1u << (5 - log_e)) - 1) << (log_e + 1);
989
10
  }
990
252
      for (s = 0; s < e - 1; s++)
991
10.9k
  for (r = 0; r < e; r++)
992
10.6k
    {
993
      /* s+1 consecutive bits to 1 (s < 63) */
994
10.6k
      imm = (1ull << (s + 1)) - 1;
995
      /* rotate right by r */
996
10.6k
      if (r != 0)
997
10.4k
        imm = (imm >> r) | ((imm << (e - r)) & mask);
998
      /* replicate the constant depending on SIMD size */
999
10.6k
      switch (log_e)
1000
10.6k
        {
1001
4
        case 1: imm = (imm <<  2) | imm;
1002
    /* Fall through.  */
1003
28
        case 2: imm = (imm <<  4) | imm;
1004
    /* Fall through.  */
1005
140
        case 3: imm = (imm <<  8) | imm;
1006
    /* Fall through.  */
1007
620
        case 4: imm = (imm << 16) | imm;
1008
    /* Fall through.  */
1009
2.60k
        case 5: imm = (imm << 32) | imm;
1010
    /* Fall through.  */
1011
10.6k
        case 6: break;
1012
0
        default: abort ();
1013
10.6k
        }
1014
10.6k
      simd_immediates[nb_imms].imm = imm;
1015
10.6k
      simd_immediates[nb_imms].encoding =
1016
10.6k
        encode_immediate_bitfield(is64, s | s_mask, r);
1017
10.6k
      nb_imms++;
1018
10.6k
    }
1019
12
    }
1020
2
  assert (nb_imms == TOTAL_IMM_NB);
1021
2
  qsort(simd_immediates, nb_imms,
1022
2
  sizeof(simd_immediates[0]), simd_imm_encoding_cmp);
1023
2
}
1024
1025
/* Return TRUE if VALUE is a valid logical immediate, i.e. bitmask, that can
1026
   be accepted by logical (immediate) instructions
1027
   e.g. ORR <Xd|SP>, <Xn>, #<imm>.
1028
1029
   ESIZE is the number of bytes in the decoded immediate value.
1030
   If ENCODING is not NULL, on the return of TRUE, the standard encoding for
1031
   VALUE will be returned in *ENCODING.  */
1032
1033
bool
1034
aarch64_logical_immediate_p (uint64_t value, int esize, aarch64_insn *encoding)
1035
355k
{
1036
355k
  simd_imm_encoding imm_enc;
1037
355k
  const simd_imm_encoding *imm_encoding;
1038
355k
  static bool initialized = false;
1039
355k
  uint64_t upper;
1040
355k
  int i;
1041
1042
355k
  DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 "), esize: %d", value,
1043
355k
         value, esize);
1044
1045
355k
  if (!initialized)
1046
2
    {
1047
2
      build_immediate_table ();
1048
2
      initialized = true;
1049
2
    }
1050
1051
  /* Allow all zeros or all ones in top bits, so that
1052
     constant expressions like ~1 are permitted.  */
1053
355k
  upper = (uint64_t) -1 << (esize * 4) << (esize * 4);
1054
355k
  if ((value & ~upper) != value && (value | upper) != value)
1055
0
    return false;
1056
1057
  /* Replicate to a full 64-bit value.  */
1058
355k
  value &= ~upper;
1059
612k
  for (i = esize * 8; i < 64; i *= 2)
1060
257k
    value |= (value << i);
1061
1062
355k
  imm_enc.imm = value;
1063
355k
  imm_encoding = (const simd_imm_encoding *)
1064
355k
    bsearch(&imm_enc, simd_immediates, TOTAL_IMM_NB,
1065
355k
            sizeof(simd_immediates[0]), simd_imm_encoding_cmp);
1066
355k
  if (imm_encoding == NULL)
1067
0
    {
1068
0
      DEBUG_TRACE ("exit with false");
1069
0
      return false;
1070
0
    }
1071
355k
  if (encoding != NULL)
1072
0
    *encoding = imm_encoding->encoding;
1073
355k
  DEBUG_TRACE ("exit with true");
1074
355k
  return true;
1075
355k
}
1076
1077
/* If 64-bit immediate IMM is in the format of
1078
   "aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh",
1079
   where a, b, c, d, e, f, g and h are independently 0 or 1, return an integer
1080
   of value "abcdefgh".  Otherwise return -1.  */
1081
int
1082
aarch64_shrink_expanded_imm8 (uint64_t imm)
1083
725
{
1084
725
  int i, ret;
1085
725
  uint32_t byte;
1086
1087
725
  ret = 0;
1088
6.52k
  for (i = 0; i < 8; i++)
1089
5.80k
    {
1090
5.80k
      byte = (imm >> (8 * i)) & 0xff;
1091
5.80k
      if (byte == 0xff)
1092
3.19k
  ret |= 1 << i;
1093
2.60k
      else if (byte != 0x00)
1094
0
  return -1;
1095
5.80k
    }
1096
725
  return ret;
1097
725
}
1098
1099
/* Utility inline functions for operand_general_constraint_met_p.  */
1100
1101
static inline void
1102
set_error (aarch64_operand_error *mismatch_detail,
1103
     enum aarch64_operand_error_kind kind, int idx,
1104
     const char* error)
1105
0
{
1106
0
  if (mismatch_detail == NULL)
1107
0
    return;
1108
0
  mismatch_detail->kind = kind;
1109
0
  mismatch_detail->index = idx;
1110
0
  mismatch_detail->error = error;
1111
0
}
1112
1113
static inline void
1114
set_syntax_error (aarch64_operand_error *mismatch_detail, int idx,
1115
      const char* error)
1116
3.33k
{
1117
3.33k
  if (mismatch_detail == NULL)
1118
3.33k
    return;
1119
0
  set_error (mismatch_detail, AARCH64_OPDE_SYNTAX_ERROR, idx, error);
1120
0
}
1121
1122
static inline void
1123
set_invalid_regno_error (aarch64_operand_error *mismatch_detail, int idx,
1124
       const char *prefix, int lower_bound, int upper_bound)
1125
0
{
1126
0
  if (mismatch_detail == NULL)
1127
0
    return;
1128
0
  set_error (mismatch_detail, AARCH64_OPDE_INVALID_REGNO, idx, NULL);
1129
0
  mismatch_detail->data[0].s = prefix;
1130
0
  mismatch_detail->data[1].i = lower_bound;
1131
0
  mismatch_detail->data[2].i = upper_bound;
1132
0
}
1133
1134
static inline void
1135
set_out_of_range_error (aarch64_operand_error *mismatch_detail,
1136
      int idx, int lower_bound, int upper_bound,
1137
      const char* error)
1138
0
{
1139
0
  if (mismatch_detail == NULL)
1140
0
    return;
1141
0
  set_error (mismatch_detail, AARCH64_OPDE_OUT_OF_RANGE, idx, error);
1142
0
  mismatch_detail->data[0].i = lower_bound;
1143
0
  mismatch_detail->data[1].i = upper_bound;
1144
0
}
1145
1146
static inline void
1147
set_imm_out_of_range_error (aarch64_operand_error *mismatch_detail,
1148
          int idx, int lower_bound, int upper_bound)
1149
49.7k
{
1150
49.7k
  if (mismatch_detail == NULL)
1151
49.7k
    return;
1152
0
  set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1153
0
        _("immediate value"));
1154
0
}
1155
1156
static inline void
1157
set_offset_out_of_range_error (aarch64_operand_error *mismatch_detail,
1158
             int idx, int lower_bound, int upper_bound)
1159
0
{
1160
0
  if (mismatch_detail == NULL)
1161
0
    return;
1162
0
  set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1163
0
        _("immediate offset"));
1164
0
}
1165
1166
static inline void
1167
set_regno_out_of_range_error (aarch64_operand_error *mismatch_detail,
1168
            int idx, int lower_bound, int upper_bound)
1169
0
{
1170
0
  if (mismatch_detail == NULL)
1171
0
    return;
1172
0
  set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1173
0
        _("register number"));
1174
0
}
1175
1176
static inline void
1177
set_elem_idx_out_of_range_error (aarch64_operand_error *mismatch_detail,
1178
         int idx, int lower_bound, int upper_bound)
1179
645
{
1180
645
  if (mismatch_detail == NULL)
1181
645
    return;
1182
0
  set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1183
0
        _("register element index"));
1184
0
}
1185
1186
static inline void
1187
set_sft_amount_out_of_range_error (aarch64_operand_error *mismatch_detail,
1188
           int idx, int lower_bound, int upper_bound)
1189
97.9k
{
1190
97.9k
  if (mismatch_detail == NULL)
1191
97.9k
    return;
1192
0
  set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1193
0
        _("shift amount"));
1194
0
}
1195
1196
/* Report that the MUL modifier in operand IDX should be in the range
1197
   [LOWER_BOUND, UPPER_BOUND].  */
1198
static inline void
1199
set_multiplier_out_of_range_error (aarch64_operand_error *mismatch_detail,
1200
           int idx, int lower_bound, int upper_bound)
1201
0
{
1202
0
  if (mismatch_detail == NULL)
1203
0
    return;
1204
0
  set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1205
0
        _("multiplier"));
1206
0
}
1207
1208
static inline void
1209
set_unaligned_error (aarch64_operand_error *mismatch_detail, int idx,
1210
         int alignment)
1211
0
{
1212
0
  if (mismatch_detail == NULL)
1213
0
    return;
1214
0
  set_error (mismatch_detail, AARCH64_OPDE_UNALIGNED, idx, NULL);
1215
0
  mismatch_detail->data[0].i = alignment;
1216
0
}
1217
1218
static inline void
1219
set_reg_list_length_error (aarch64_operand_error *mismatch_detail, int idx,
1220
         int expected_num)
1221
787
{
1222
787
  if (mismatch_detail == NULL)
1223
787
    return;
1224
0
  set_error (mismatch_detail, AARCH64_OPDE_REG_LIST_LENGTH, idx, NULL);
1225
0
  mismatch_detail->data[0].i = 1 << expected_num;
1226
0
}
1227
1228
static inline void
1229
set_reg_list_stride_error (aarch64_operand_error *mismatch_detail, int idx,
1230
         int expected_num)
1231
0
{
1232
0
  if (mismatch_detail == NULL)
1233
0
    return;
1234
0
  set_error (mismatch_detail, AARCH64_OPDE_REG_LIST_STRIDE, idx, NULL);
1235
0
  mismatch_detail->data[0].i = 1 << expected_num;
1236
0
}
1237
1238
static inline void
1239
set_invalid_vg_size (aarch64_operand_error *mismatch_detail,
1240
         int idx, int expected)
1241
0
{
1242
0
  if (mismatch_detail == NULL)
1243
0
    return;
1244
0
  set_error (mismatch_detail, AARCH64_OPDE_INVALID_VG_SIZE, idx, NULL);
1245
0
  mismatch_detail->data[0].i = expected;
1246
0
}
1247
1248
static inline void
1249
set_other_error (aarch64_operand_error *mismatch_detail, int idx,
1250
     const char* error)
1251
44.9k
{
1252
44.9k
  if (mismatch_detail == NULL)
1253
44.9k
    return;
1254
0
  set_error (mismatch_detail, AARCH64_OPDE_OTHER_ERROR, idx, error);
1255
0
}
1256
1257
/* Check that indexed register operand OPND has a register in the range
1258
   [MIN_REGNO, MAX_REGNO] and an index in the range [MIN_INDEX, MAX_INDEX].
1259
   PREFIX is the register prefix, such as "z" for SVE vector registers.  */
1260
1261
static bool
1262
check_reglane (const aarch64_opnd_info *opnd,
1263
         aarch64_operand_error *mismatch_detail, int idx,
1264
         const char *prefix, int min_regno, int max_regno,
1265
         int min_index, int max_index)
1266
94.9k
{
1267
94.9k
  if (!value_in_range_p (opnd->reglane.regno, min_regno, max_regno))
1268
0
    {
1269
0
      set_invalid_regno_error (mismatch_detail, idx, prefix, min_regno,
1270
0
             max_regno);
1271
0
      return false;
1272
0
    }
1273
94.9k
  if (!value_in_range_p (opnd->reglane.index, min_index, max_index))
1274
0
    {
1275
0
      set_elem_idx_out_of_range_error (mismatch_detail, idx, min_index,
1276
0
               max_index);
1277
0
      return false;
1278
0
    }
1279
94.9k
  return true;
1280
94.9k
}
1281
1282
/* Check that register list operand OPND has NUM_REGS registers and a
1283
   register stride of STRIDE.  */
1284
1285
static bool
1286
check_reglist (const aarch64_opnd_info *opnd,
1287
         aarch64_operand_error *mismatch_detail, int idx,
1288
         int num_regs, int stride)
1289
402k
{
1290
402k
  if (opnd->reglist.num_regs != num_regs)
1291
787
    {
1292
787
      set_reg_list_length_error (mismatch_detail, idx, num_regs);
1293
787
      return false;
1294
787
    }
1295
401k
  if (opnd->reglist.stride != stride)
1296
0
    {
1297
0
      set_reg_list_stride_error (mismatch_detail, idx, stride);
1298
0
      return false;
1299
0
    }
1300
401k
  return true;
1301
401k
}
1302
1303
typedef struct
1304
{
1305
  int64_t min;
1306
  int64_t max;
1307
} imm_range_t;
1308
1309
static imm_range_t
1310
imm_range_min_max (unsigned size, bool signed_rng)
1311
0
{
1312
0
  assert (size < 63);
1313
0
  imm_range_t r;
1314
0
  if (signed_rng)
1315
0
    {
1316
0
      r.max = (((int64_t) 0x1) << (size - 1)) - 1;
1317
0
      r.min = - r.max - 1;
1318
0
    }
1319
0
  else
1320
0
    {
1321
0
      r.max = (((int64_t) 0x1) << size) - 1;
1322
0
      r.min = 0;
1323
0
    }
1324
0
  return r;
1325
0
}
1326
1327
/* Check that an immediate value is in the range provided by the
1328
   operand type.  */
1329
static bool
1330
check_immediate_out_of_range (int64_t imm,
1331
            enum aarch64_opnd type,
1332
            aarch64_operand_error *mismatch_detail,
1333
            int idx)
1334
1.37M
{
1335
1.37M
  const aarch64_operand *operand = get_operand_from_code (type);
1336
1.37M
  uint8_t size = get_operand_fields_width (operand);
1337
1.37M
  bool unsigned_imm = operand_need_unsigned_offset (operand);
1338
1.37M
  bool (*value_fit_field) (int64_t, unsigned)
1339
1.37M
    = (unsigned_imm
1340
1.37M
      ? value_fit_unsigned_field_p
1341
1.37M
      : value_fit_signed_field_p);
1342
1343
1.37M
  if (!value_fit_field (imm, size))
1344
0
    {
1345
0
      imm_range_t rng = imm_range_min_max (size, !unsigned_imm);
1346
0
      set_imm_out_of_range_error (mismatch_detail, idx, rng.min, rng.max);
1347
0
      return false;
1348
0
    }
1349
1.37M
  return true;
1350
1.37M
}
1351
1352
/* Check that indexed ZA operand OPND has:
1353
1354
   - a selection register in the range [MIN_WREG, MIN_WREG + 3]
1355
1356
   - RANGE_SIZE consecutive immediate offsets.
1357
1358
   - an initial immediate offset that is a multiple of RANGE_SIZE
1359
     in the range [0, MAX_VALUE * RANGE_SIZE]
1360
1361
   - a vector group size of GROUP_SIZE.
1362
1363
   - STATUS_VG for cases where VGx2 or VGx4 is mandatory.  */
1364
static bool
1365
check_za_access (const aarch64_opnd_info *opnd,
1366
     aarch64_operand_error *mismatch_detail, int idx,
1367
     int min_wreg, int max_value, unsigned int range_size,
1368
     int group_size, bool status_vg)
1369
204k
{
1370
204k
  if (!value_in_range_p (opnd->indexed_za.index.regno, min_wreg, min_wreg + 3))
1371
0
    {
1372
0
      if (min_wreg == 12)
1373
0
  set_other_error (mismatch_detail, idx,
1374
0
       _("expected a selection register in the"
1375
0
         " range w12-w15"));
1376
0
      else if (min_wreg == 8)
1377
0
  set_other_error (mismatch_detail, idx,
1378
0
       _("expected a selection register in the"
1379
0
         " range w8-w11"));
1380
0
      else
1381
0
  abort ();
1382
0
      return false;
1383
0
    }
1384
1385
204k
  int max_index = max_value * range_size;
1386
204k
  if (!value_in_range_p (opnd->indexed_za.index.imm, 0, max_index))
1387
0
    {
1388
0
      set_offset_out_of_range_error (mismatch_detail, idx, 0, max_index);
1389
0
      return false;
1390
0
    }
1391
1392
204k
  if ((opnd->indexed_za.index.imm % range_size) != 0)
1393
0
    {
1394
0
      assert (range_size == 2 || range_size == 4);
1395
0
      set_other_error (mismatch_detail, idx,
1396
0
           range_size == 2
1397
0
           ? _("starting offset is not a multiple of 2")
1398
0
           : _("starting offset is not a multiple of 4"));
1399
0
      return false;
1400
0
    }
1401
1402
204k
  if (opnd->indexed_za.index.countm1 != range_size - 1)
1403
0
    {
1404
0
      if (range_size == 1)
1405
0
  set_other_error (mismatch_detail, idx,
1406
0
       _("expected a single offset rather than"
1407
0
         " a range"));
1408
0
      else if (range_size == 2)
1409
0
  set_other_error (mismatch_detail, idx,
1410
0
       _("expected a range of two offsets"));
1411
0
      else if (range_size == 4)
1412
0
  set_other_error (mismatch_detail, idx,
1413
0
       _("expected a range of four offsets"));
1414
0
      else
1415
0
  abort ();
1416
0
      return false;
1417
0
    }
1418
1419
  /* The vector group specifier is optional in assembly code.  */
1420
204k
  if (opnd->indexed_za.group_size != group_size
1421
0
      && (status_vg || opnd->indexed_za.group_size != 0 ))
1422
0
    {
1423
0
      set_invalid_vg_size (mismatch_detail, idx, group_size);
1424
0
      return false;
1425
0
    }
1426
1427
204k
  return true;
1428
204k
}
1429
1430
/* Given a load/store operation, calculate the size of transferred data via a
1431
   cumulative sum of qualifier sizes preceding the address operand in the
1432
   OPNDS operand list argument.  */
1433
int
1434
calc_ldst_datasize (const aarch64_opnd_info *opnds)
1435
18.8k
{
1436
18.8k
  unsigned num_bytes = 0; /* total number of bytes transferred.  */
1437
18.8k
  enum aarch64_operand_class opnd_class;
1438
18.8k
  enum aarch64_opnd type;
1439
1440
55.8k
  for (int i = 0; i < AARCH64_MAX_OPND_NUM; i++)
1441
55.8k
    {
1442
55.8k
      type = opnds[i].type;
1443
55.8k
      opnd_class = aarch64_operands[type].op_class;
1444
55.8k
      if (opnd_class == AARCH64_OPND_CLASS_ADDRESS)
1445
18.8k
  break;
1446
36.9k
      num_bytes += aarch64_get_qualifier_esize (opnds[i].qualifier);
1447
36.9k
    }
1448
18.8k
  return num_bytes;
1449
18.8k
}
1450
1451
1452
/* General constraint checking based on operand code.
1453
1454
   Return 1 if OPNDS[IDX] meets the general constraint of operand code TYPE
1455
   as the IDXth operand of opcode OPCODE.  Otherwise return 0.
1456
1457
   This function has to be called after the qualifiers for all operands
1458
   have been resolved.
1459
1460
   Mismatching error message is returned in *MISMATCH_DETAIL upon request,
1461
   i.e. when MISMATCH_DETAIL is non-NULL.  This avoids the generation
1462
   of error message during the disassembling where error message is not
1463
   wanted.  We avoid the dynamic construction of strings of error messages
1464
   here (i.e. in libopcodes), as it is costly and complicated; instead, we
1465
   use a combination of error code, static string and some integer data to
1466
   represent an error.  */
1467
1468
static bool
1469
operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
1470
          enum aarch64_opnd type,
1471
          const aarch64_opcode *opcode,
1472
          aarch64_operand_error *mismatch_detail)
1473
19.1M
{
1474
19.1M
  unsigned num, modifiers, shift;
1475
19.1M
  unsigned char size;
1476
19.1M
  int64_t imm, min_value, max_value;
1477
19.1M
  uint64_t uvalue, mask;
1478
19.1M
  const aarch64_opnd_info *opnd = opnds + idx;
1479
19.1M
  aarch64_opnd_qualifier_t qualifier = opnd->qualifier;
1480
19.1M
  int i;
1481
1482
19.1M
  assert (opcode->operands[idx] == opnd->type && opnd->type == type);
1483
1484
19.1M
  switch (aarch64_operands[type].op_class)
1485
19.1M
    {
1486
6.23M
    case AARCH64_OPND_CLASS_INT_REG:
1487
      /* Check for pair of xzr registers.  */
1488
6.23M
      if (type == AARCH64_OPND_PAIRREG_OR_XZR
1489
4.42k
    && opnds[idx - 1].reg.regno == 0x1f)
1490
1.91k
  {
1491
1.91k
    if (opnds[idx].reg.regno != 0x1f)
1492
0
      {
1493
0
        set_syntax_error (mismatch_detail, idx - 1,
1494
0
        _("second reg in pair should be xzr if first is"
1495
0
          " xzr"));
1496
0
        return false;
1497
0
      }
1498
1.91k
  }
1499
      /* Check pair reg constraints for instructions taking a pair of
1500
   consecutively-numbered general-purpose registers.  */
1501
6.22M
      else if (type == AARCH64_OPND_PAIRREG
1502
6.22M
         || type == AARCH64_OPND_PAIRREG_OR_XZR)
1503
9.98k
  {
1504
9.98k
    assert (idx == 1 || idx == 2 || idx == 3 || idx == 5);
1505
9.98k
    if (opnds[idx - 1].reg.regno % 2 != 0)
1506
3.33k
      {
1507
3.33k
        set_syntax_error (mismatch_detail, idx - 1,
1508
3.33k
        _("reg pair must start from even reg"));
1509
3.33k
        return false;
1510
3.33k
      }
1511
6.65k
    if (opnds[idx].reg.regno != opnds[idx - 1].reg.regno + 1)
1512
0
      {
1513
0
        set_syntax_error (mismatch_detail, idx,
1514
0
        _("reg pair must be contiguous"));
1515
0
        return false;
1516
0
      }
1517
6.65k
    break;
1518
6.65k
  }
1519
1520
      /* <Xt> may be optional in some IC and TLBI instructions.  */
1521
6.22M
      if (type == AARCH64_OPND_Rt_SYS)
1522
953
  {
1523
953
    assert (idx == 1 && (aarch64_get_operand_class (opnds[0].type)
1524
953
             == AARCH64_OPND_CLASS_SYSTEM));
1525
953
    if (!(opnds[1].present && aarch64_sys_ins_reg_tlbid_xt (opnds[0].sysins_op)))
1526
917
      {
1527
917
        if (opnds[1].present
1528
902
      && !aarch64_sys_ins_reg_has_xt (opnds[0].sysins_op))
1529
566
    {
1530
566
      set_other_error (mismatch_detail, idx, _("extraneous register"));
1531
566
      return false;
1532
566
    }
1533
351
        if (!opnds[1].present
1534
15
      && aarch64_sys_ins_reg_has_xt (opnds[0].sysins_op))
1535
0
    {
1536
0
      set_other_error (mismatch_detail, idx, _("missing register"));
1537
0
      return false;
1538
0
    }
1539
351
     }
1540
953
  }
1541
6.22M
      break;
1542
1543
6.22M
    case AARCH64_OPND_CLASS_SVE_REG:
1544
1.71M
      switch (type)
1545
1.71M
  {
1546
5.36k
  case AARCH64_OPND_SVE_Zm3_INDEX:
1547
15.5k
  case AARCH64_OPND_SVE_Zm3_22_INDEX:
1548
16.2k
  case AARCH64_OPND_SVE_Zm3_19_INDEX:
1549
22.8k
  case AARCH64_OPND_SVE_Zm3_11_INDEX:
1550
26.5k
  case AARCH64_OPND_SVE_Zm3_10_INDEX:
1551
30.2k
  case AARCH64_OPND_SVE_Zm4_11_INDEX:
1552
36.0k
  case AARCH64_OPND_SVE_Zm4_INDEX:
1553
36.0k
    size = get_operand_fields_width (get_operand_from_code (type));
1554
36.0k
    shift = get_operand_specific_data (&aarch64_operands[type]);
1555
36.0k
    if (!check_reglane (opnd, mismatch_detail, idx,
1556
36.0k
            "z", 0, (1 << shift) - 1,
1557
36.0k
            0, (1u << (size - shift)) - 1))
1558
0
      return false;
1559
36.0k
    break;
1560
1561
36.0k
  case AARCH64_OPND_SVE_Zm1_23_INDEX:
1562
467
    size = get_operand_fields_width (get_operand_from_code (type));
1563
467
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31, 0, 1))
1564
0
      return 0;
1565
467
    break;
1566
1567
467
  case AARCH64_OPND_SME_Zn_INDEX2_19:
1568
1.31k
  case AARCH64_OPND_SVE_Zm2_22_INDEX:
1569
1.31k
    size = get_operand_fields_width (get_operand_from_code (type));
1570
1.31k
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31, 0, 3))
1571
0
      return 0;
1572
1.31k
    break;
1573
1574
2.77k
  case AARCH64_OPND_SVE_Zn_INDEX:
1575
2.77k
    size = aarch64_get_qualifier_esize (opnd->qualifier);
1576
2.77k
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31,
1577
2.77k
            0, 64 / size - 1))
1578
0
      return false;
1579
2.77k
    break;
1580
1581
2.77k
  case AARCH64_OPND_SVE_Zn_5_INDEX:
1582
399
    size = aarch64_get_qualifier_esize (opnd->qualifier);
1583
399
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31,
1584
399
            0, 16 / size - 1))
1585
0
      return false;
1586
399
    break;
1587
1588
399
  case AARCH64_OPND_SME_PNn3_INDEX1:
1589
182
  case AARCH64_OPND_SME_PNn3_INDEX2:
1590
182
    size = get_operand_field_width (get_operand_from_code (type), 0);
1591
182
    if (!check_reglane (opnd, mismatch_detail, idx, "pn", 8, 15,
1592
182
            0, (1 << size) - 1))
1593
0
      return false;
1594
182
    break;
1595
1596
1.00k
  case AARCH64_OPND_SVE_Zm3_12_INDEX:
1597
1.29k
  case AARCH64_OPND_SME_Zn_INDEX1_16:
1598
1.55k
  case AARCH64_OPND_SME_Zn_INDEX2_15:
1599
2.21k
  case AARCH64_OPND_SME_Zn_INDEX2_16:
1600
2.47k
  case AARCH64_OPND_SME_Zn_INDEX3_14:
1601
2.66k
  case AARCH64_OPND_SME_Zn_INDEX3_15:
1602
2.86k
  case AARCH64_OPND_SME_Zn_INDEX4_14:
1603
2.94k
  case AARCH64_OPND_SVE_Zn0_INDEX:
1604
3.03k
  case AARCH64_OPND_SVE_Zn1_17_INDEX:
1605
3.10k
  case AARCH64_OPND_SVE_Zn2_18_INDEX:
1606
3.37k
  case AARCH64_OPND_SVE_Zn3_22_INDEX:
1607
3.46k
  case AARCH64_OPND_SVE_Zd0_INDEX:
1608
3.56k
  case AARCH64_OPND_SVE_Zd1_17_INDEX:
1609
3.64k
  case AARCH64_OPND_SVE_Zd2_18_INDEX:
1610
3.71k
  case AARCH64_OPND_SVE_Zd3_22_INDEX:
1611
3.71k
    size = get_operand_fields_width (get_operand_from_code (type)) - 5;
1612
3.71k
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31,
1613
3.71k
            0, (1 << size) - 1))
1614
0
      return false;
1615
3.71k
    break;
1616
1617
3.71k
  case AARCH64_OPND_SME_Zm_INDEX1:
1618
3.24k
  case AARCH64_OPND_SME_Zm_INDEX2:
1619
3.79k
  case AARCH64_OPND_SME_Zm_INDEX2_3:
1620
5.76k
  case AARCH64_OPND_SME_Zm_INDEX3_1:
1621
8.55k
  case AARCH64_OPND_SME_Zm_INDEX3_2:
1622
9.32k
  case AARCH64_OPND_SME_Zm_INDEX3_3:
1623
14.2k
  case AARCH64_OPND_SME_Zm_INDEX3_10:
1624
16.2k
  case AARCH64_OPND_SME_Zm_INDEX4_1:
1625
17.4k
  case AARCH64_OPND_SME_Zm_INDEX4_2:
1626
33.6k
  case AARCH64_OPND_SME_Zm_INDEX4_3:
1627
40.2k
  case AARCH64_OPND_SME_Zm_INDEX4_10:
1628
40.2k
    size = get_operand_fields_width (get_operand_from_code (type)) - 5;
1629
40.2k
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 15,
1630
40.2k
            0, (1 << size) - 1))
1631
0
      return false;
1632
40.2k
    break;
1633
1634
40.2k
  case AARCH64_OPND_SME_Zk_INDEX:
1635
5.02k
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31, 0, 3))
1636
0
      return false;
1637
5.02k
    if ((opnd->reglane.regno & 20) != 20)
1638
0
      {
1639
0
        set_other_error (mismatch_detail, idx,
1640
0
             _("register out of range"));
1641
0
        return false;
1642
0
      }
1643
5.02k
    break;
1644
1645
8.50k
  case AARCH64_OPND_SME_Zm:
1646
8.54k
  case AARCH64_OPND_SME_Zm_17:
1647
8.54k
    if (opnd->reg.regno > 15)
1648
0
      {
1649
0
        set_invalid_regno_error (mismatch_detail, idx, "z", 0, 15);
1650
0
        return false;
1651
0
      }
1652
8.54k
    break;
1653
1654
10.1k
  case AARCH64_OPND_SME_Zn_6_3:
1655
10.1k
    if (opnd->reg.regno > 15 || opnd->reg.regno % 2 != 0)
1656
0
      {
1657
0
        set_other_error (mismatch_detail, idx,
1658
0
             _("register out of range"));
1659
0
        return false;
1660
0
      }
1661
10.1k
    break;
1662
1663
10.1k
  case AARCH64_OPND_SME_Zm_17_3:
1664
9.81k
    if (opnd->reg.regno < 16 || opnd->reg.regno % 2 != 0)
1665
0
      {
1666
0
        set_other_error (mismatch_detail, idx,
1667
0
             _("register out of range"));
1668
0
        return false;
1669
0
      }
1670
9.81k
    break;
1671
1672
10.3k
  case AARCH64_OPND_SME_PnT_Wm_imm:
1673
10.3k
    size = aarch64_get_qualifier_esize (opnd->qualifier);
1674
10.3k
    max_value = 16 / size - 1;
1675
10.3k
    if (!check_za_access (opnd, mismatch_detail, idx,
1676
10.3k
        12, max_value, 1, 0, get_opcode_dependent_value (opcode)))
1677
0
      return false;
1678
10.3k
    break;
1679
1680
1.58M
  default:
1681
1.58M
    break;
1682
1.71M
  }
1683
1.71M
      break;
1684
1685
1.71M
    case AARCH64_OPND_CLASS_SVE_REGLIST:
1686
364k
      switch (type)
1687
364k
  {
1688
903
  case AARCH64_OPND_SME_Pdx2:
1689
23.7k
  case AARCH64_OPND_SME_Zdnx2:
1690
31.7k
  case AARCH64_OPND_SME_Zdnx4:
1691
32.1k
  case AARCH64_OPND_SME_Znx2_6_3:
1692
32.7k
  case AARCH64_OPND_SME_Zmx2_17_3:
1693
35.6k
  case AARCH64_OPND_SME_Zmx2:
1694
36.1k
  case AARCH64_OPND_SME_Zmx4:
1695
55.0k
  case AARCH64_OPND_SME_Znx2:
1696
55.0k
  case AARCH64_OPND_SME_Znx2_BIT_INDEX:
1697
61.1k
  case AARCH64_OPND_SME_Znx4:
1698
61.1k
    num = get_operand_specific_data (&aarch64_operands[type]);
1699
61.1k
    if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
1700
0
      return false;
1701
61.1k
    if (((opnd->reglist.first_regno % num) != 0)
1702
61.1k
        || (type == AARCH64_OPND_SME_Znx2_6_3
1703
347
      && opnd->reglist.first_regno > 15)
1704
61.1k
        || (type == AARCH64_OPND_SME_Zmx2_17_3
1705
637
      && opnd->reglist.first_regno < 16))
1706
0
      {
1707
0
        set_other_error (mismatch_detail, idx,
1708
0
             _("start register out of range"));
1709
0
        return false;
1710
0
      }
1711
61.1k
    break;
1712
1713
61.1k
  case AARCH64_OPND_SME_Ztx2_STRIDED:
1714
13.3k
  case AARCH64_OPND_SME_Ztx4_STRIDED:
1715
    /* 2-register lists have a stride of 8 and 4-register lists
1716
       have a stride of 4.  */
1717
13.3k
    num = get_operand_specific_data (&aarch64_operands[type]);
1718
13.3k
    if (!check_reglist (opnd, mismatch_detail, idx, num, 16 / num))
1719
0
      return false;
1720
13.3k
    num = 16 | (opnd->reglist.stride - 1);
1721
13.3k
    if ((opnd->reglist.first_regno & ~num) != 0)
1722
0
      {
1723
0
        set_other_error (mismatch_detail, idx,
1724
0
             _("start register out of range"));
1725
0
        return false;
1726
0
      }
1727
13.3k
    break;
1728
1729
13.3k
  case AARCH64_OPND_SME_PdxN:
1730
12.8k
  case AARCH64_OPND_SVE_ZnxN:
1731
289k
  case AARCH64_OPND_SVE_ZtxN:
1732
289k
    num = get_opcode_dependent_value (opcode);
1733
289k
    if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
1734
0
      return false;
1735
289k
    break;
1736
1737
289k
  case AARCH64_OPND_SME_Zmx2_INDEX_22:
1738
359
    num = get_operand_specific_data (&aarch64_operands[type]);
1739
359
    if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
1740
0
        return false;
1741
359
    break;
1742
1743
359
  case AARCH64_OPND_SME_Zn7xN_UNTYPED:
1744
123
    num = get_opcode_dependent_value (opcode);
1745
123
    if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
1746
0
        return false;
1747
123
    if (opnd->reglist.first_regno > 7)
1748
0
    {
1749
0
      set_other_error (mismatch_detail, idx, _("start register out of range"));
1750
0
      return false;
1751
0
    }
1752
123
    break;
1753
1754
123
  default:
1755
0
    abort ();
1756
364k
  }
1757
364k
      break;
1758
1759
364k
    case AARCH64_OPND_CLASS_ZA_ACCESS:
1760
194k
      switch (type)
1761
194k
  {
1762
1.45k
  case AARCH64_OPND_SME_ZA_HV_idx_src:
1763
83.7k
  case AARCH64_OPND_SME_ZA_HV_idx_dest:
1764
130k
  case AARCH64_OPND_SME_ZA_HV_idx_ldstr:
1765
130k
    size = aarch64_get_qualifier_esize (opnd->qualifier);
1766
130k
    max_value = 16 / size - 1;
1767
130k
    if (!check_za_access (opnd, mismatch_detail, idx, 12, max_value, 1,
1768
130k
        get_opcode_dependent_value (opcode),
1769
130k
        get_opcode_dependent_vg_status (opcode)))
1770
0
      return false;
1771
130k
    break;
1772
1773
130k
  case AARCH64_OPND_SME_ZA_array_off4:
1774
996
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 15, 1,
1775
996
        get_opcode_dependent_value (opcode),
1776
996
        get_opcode_dependent_vg_status (opcode)))
1777
0
      return false;
1778
996
    break;
1779
1780
11.0k
  case AARCH64_OPND_SME_ZA_array_off3_0:
1781
11.7k
  case AARCH64_OPND_SME_ZA_array_off3_5:
1782
11.7k
    if (!check_za_access (opnd, mismatch_detail, idx, 8, 7, 1,
1783
11.7k
        get_opcode_dependent_value (opcode),
1784
11.7k
        get_opcode_dependent_vg_status (opcode)))
1785
0
      return false;
1786
11.7k
    break;
1787
1788
11.7k
  case AARCH64_OPND_SME_ZA_array_off1x4:
1789
6.49k
    if (!check_za_access (opnd, mismatch_detail, idx, 8, 1, 4,
1790
6.49k
        get_opcode_dependent_value (opcode),
1791
6.49k
        get_opcode_dependent_vg_status (opcode)))
1792
0
      return false;
1793
6.49k
    break;
1794
1795
6.49k
  case AARCH64_OPND_SME_ZA_array_off2x2:
1796
5.84k
    if (!check_za_access (opnd, mismatch_detail, idx, 8, 3, 2,
1797
5.84k
        get_opcode_dependent_value (opcode),
1798
5.84k
        get_opcode_dependent_vg_status (opcode)))
1799
0
      return false;
1800
5.84k
    break;
1801
1802
7.83k
  case AARCH64_OPND_SME_ZA_array_off2x4:
1803
7.83k
    if (!check_za_access (opnd, mismatch_detail, idx, 8, 3, 4,
1804
7.83k
        get_opcode_dependent_value (opcode),
1805
7.83k
        get_opcode_dependent_vg_status (opcode)))
1806
0
      return false;
1807
7.83k
    break;
1808
1809
21.1k
  case AARCH64_OPND_SME_ZA_array_off3x2:
1810
21.1k
    if (!check_za_access (opnd, mismatch_detail, idx, 8, 7, 2,
1811
21.1k
        get_opcode_dependent_value (opcode),
1812
21.1k
        get_opcode_dependent_vg_status (opcode)))
1813
0
      return false;
1814
21.1k
    break;
1815
1816
21.1k
  case AARCH64_OPND_SME_ZA_array_vrsb_1:
1817
107
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 7, 2,
1818
107
        get_opcode_dependent_value (opcode),
1819
107
        get_opcode_dependent_vg_status (opcode)))
1820
0
      return false;
1821
107
    break;
1822
1823
107
  case AARCH64_OPND_SME_ZA_array_vrsh_1:
1824
48
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 3, 2,
1825
48
        get_opcode_dependent_value (opcode),
1826
48
        get_opcode_dependent_vg_status (opcode)))
1827
0
      return false;
1828
48
    break;
1829
1830
119
  case AARCH64_OPND_SME_ZA_array_vrss_1:
1831
119
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 1, 2,
1832
119
        get_opcode_dependent_value (opcode),
1833
119
        get_opcode_dependent_vg_status (opcode)))
1834
0
      return false;
1835
119
    break;
1836
1837
262
  case AARCH64_OPND_SME_ZA_array_vrsd_1:
1838
262
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 0, 2,
1839
262
        get_opcode_dependent_value (opcode),
1840
262
        get_opcode_dependent_vg_status (opcode)))
1841
0
      return false;
1842
262
    break;
1843
1844
300
  case AARCH64_OPND_SME_ZA_array_vrsb_2:
1845
300
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 3, 4,
1846
300
        get_opcode_dependent_value (opcode),
1847
300
        get_opcode_dependent_vg_status (opcode)))
1848
0
      return false;
1849
300
    break;
1850
1851
300
  case AARCH64_OPND_SME_ZA_array_vrsh_2:
1852
108
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 1, 4,
1853
108
        get_opcode_dependent_value (opcode),
1854
108
        get_opcode_dependent_vg_status (opcode)))
1855
0
      return false;
1856
108
    break;
1857
1858
890
  case AARCH64_OPND_SME_ZA_ARRAY4:
1859
890
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 15, 1,
1860
890
        get_opcode_dependent_value (opcode),
1861
890
        get_opcode_dependent_vg_status (opcode)))
1862
0
      return false;
1863
890
    break;
1864
1865
890
  case AARCH64_OPND_SME_ZA_array_vrss_2:
1866
625
  case AARCH64_OPND_SME_ZA_array_vrsd_2:
1867
625
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 0, 4,
1868
625
        get_opcode_dependent_value (opcode),
1869
625
        get_opcode_dependent_vg_status (opcode)))
1870
0
      return false;
1871
625
    break;
1872
1873
4.92k
  case AARCH64_OPND_SME_ZA_HV_idx_srcxN:
1874
6.98k
  case AARCH64_OPND_SME_ZA_HV_idx_destxN:
1875
6.98k
    size = aarch64_get_qualifier_esize (opnd->qualifier);
1876
6.98k
    num = get_opcode_dependent_value (opcode);
1877
6.98k
    max_value = 16 / num / size;
1878
6.98k
    if (max_value > 0)
1879
6.81k
      max_value -= 1;
1880
6.98k
    if (!check_za_access (opnd, mismatch_detail, idx, 12, max_value, num,
1881
6.98k
        0, get_opcode_dependent_value (opcode)))
1882
0
      return false;
1883
6.98k
    break;
1884
1885
6.98k
  default:
1886
0
    abort ();
1887
194k
  }
1888
194k
      break;
1889
1890
1.07M
    case AARCH64_OPND_CLASS_PRED_REG:
1891
1.07M
      switch (type)
1892
1.07M
  {
1893
2.73k
  case AARCH64_OPND_SME_PNd3:
1894
34.8k
  case AARCH64_OPND_SME_PNg3:
1895
34.8k
    if (opnd->reg.regno < 8)
1896
0
      {
1897
0
        set_invalid_regno_error (mismatch_detail, idx, "pn", 8, 15);
1898
0
        return false;
1899
0
      }
1900
34.8k
    break;
1901
1902
1.04M
  default:
1903
1.04M
    if (opnd->reg.regno >= 8
1904
75.4k
        && get_operand_fields_width (get_operand_from_code (type)) == 3)
1905
0
      {
1906
0
        set_invalid_regno_error (mismatch_detail, idx, "p", 0, 7);
1907
0
        return false;
1908
0
      }
1909
1.04M
    break;
1910
1.07M
  }
1911
1.07M
      break;
1912
1913
1.07M
    case AARCH64_OPND_CLASS_COND:
1914
26.1k
      if (type == AARCH64_OPND_COND1
1915
619
    && (opnds[idx].cond->value & 0xe) == 0xe)
1916
0
  {
1917
    /* Not allow AL or NV.  */
1918
0
    set_syntax_error (mismatch_detail, idx, NULL);
1919
0
  }
1920
26.1k
      break;
1921
1922
3.30M
    case AARCH64_OPND_CLASS_ADDRESS:
1923
      /* Check writeback.  */
1924
3.30M
      switch (opcode->iclass)
1925
3.30M
  {
1926
247k
  case ldst_pos:
1927
331k
  case ldst_unscaled:
1928
480k
  case ldstnapair_offs:
1929
667k
  case ldstpair_off:
1930
681k
  case ldst_unpriv:
1931
681k
    if (opnd->addr.writeback == 1)
1932
0
      {
1933
0
        set_syntax_error (mismatch_detail, idx,
1934
0
        _("unexpected address writeback"));
1935
0
        return false;
1936
0
      }
1937
681k
    break;
1938
681k
  case ldst_imm10:
1939
10.3k
    if (opnd->addr.writeback == 1 && opnd->addr.preind != 1)
1940
0
      {
1941
0
        set_syntax_error (mismatch_detail, idx,
1942
0
        _("unexpected address writeback"));
1943
0
        return false;
1944
0
      }
1945
10.3k
    break;
1946
52.3k
  case ldst_imm9:
1947
307k
  case ldstpair_indexed:
1948
314k
  case asisdlsep:
1949
328k
  case asisdlsop:
1950
328k
    if (opnd->addr.writeback == 0)
1951
0
      {
1952
0
        set_syntax_error (mismatch_detail, idx,
1953
0
        _("address writeback expected"));
1954
0
        return false;
1955
0
      }
1956
328k
    break;
1957
328k
  case rcpc3:
1958
24.4k
    if (opnd->addr.writeback)
1959
1.82k
      if ((type == AARCH64_OPND_RCPC3_ADDR_PREIND_WB
1960
268
     && !opnd->addr.preind)
1961
1.82k
    || (type == AARCH64_OPND_RCPC3_ADDR_POSTIND
1962
94
        && !opnd->addr.postind))
1963
0
        {
1964
0
    set_syntax_error (mismatch_detail, idx,
1965
0
          _("unexpected address writeback"));
1966
0
    return false;
1967
0
        }
1968
1969
24.4k
    break;
1970
2.26M
  default:
1971
2.26M
    assert (opnd->addr.writeback == 0);
1972
2.26M
    break;
1973
3.30M
  }
1974
3.30M
      switch (type)
1975
3.30M
  {
1976
564k
  case AARCH64_OPND_ADDR_SIMM7:
1977
    /* Scaled signed 7 bits immediate offset.  */
1978
    /* Get the size of the data element that is accessed, which may be
1979
       different from that of the source register size,
1980
       e.g. in strb/ldrb.  */
1981
564k
    size = aarch64_get_qualifier_esize (opnd->qualifier);
1982
564k
    if (!value_in_range_p (opnd->addr.offset.imm, -64 * size, 63 * size))
1983
0
      {
1984
0
        set_offset_out_of_range_error (mismatch_detail, idx,
1985
0
               -64 * size, 63 * size);
1986
0
        return false;
1987
0
      }
1988
564k
    if (!value_aligned_p (opnd->addr.offset.imm, size))
1989
0
      {
1990
0
        set_unaligned_error (mismatch_detail, idx, size);
1991
0
        return false;
1992
0
      }
1993
564k
    break;
1994
564k
  case AARCH64_OPND_ADDR_OFFSET:
1995
141k
  case AARCH64_OPND_ADDR_SIMM9:
1996
    /* Unscaled signed 9 bits immediate offset.  */
1997
141k
    if (!value_in_range_p (opnd->addr.offset.imm, -256, 255))
1998
0
      {
1999
0
        set_offset_out_of_range_error (mismatch_detail, idx, -256, 255);
2000
0
        return false;
2001
0
      }
2002
141k
    break;
2003
2004
141k
  case AARCH64_OPND_ADDR_SIMM10:
2005
    /* Scaled signed 10 bits immediate offset.  */
2006
10.3k
    if (!value_in_range_p (opnd->addr.offset.imm, -4096, 4088))
2007
0
      {
2008
0
        set_offset_out_of_range_error (mismatch_detail, idx, -4096, 4088);
2009
0
        return false;
2010
0
      }
2011
10.3k
    if (!value_aligned_p (opnd->addr.offset.imm, 8))
2012
0
      {
2013
0
        set_unaligned_error (mismatch_detail, idx, 8);
2014
0
        return false;
2015
0
      }
2016
10.3k
    break;
2017
2018
26.5k
  case AARCH64_OPND_ADDR_SIMM11:
2019
    /* Signed 11 bits immediate offset (multiple of 16).  */
2020
26.5k
    if (!value_in_range_p (opnd->addr.offset.imm, -1024, 1008))
2021
0
      {
2022
0
        set_offset_out_of_range_error (mismatch_detail, idx, -1024, 1008);
2023
0
        return false;
2024
0
      }
2025
2026
26.5k
    if (!value_aligned_p (opnd->addr.offset.imm, 16))
2027
0
      {
2028
0
        set_unaligned_error (mismatch_detail, idx, 16);
2029
0
        return false;
2030
0
      }
2031
26.5k
    break;
2032
2033
26.5k
  case AARCH64_OPND_ADDR_SIMM13:
2034
    /* Signed 13 bits immediate offset (multiple of 16).  */
2035
9.17k
    if (!value_in_range_p (opnd->addr.offset.imm, -4096, 4080))
2036
0
      {
2037
0
        set_offset_out_of_range_error (mismatch_detail, idx, -4096, 4080);
2038
0
        return false;
2039
0
      }
2040
2041
9.17k
    if (!value_aligned_p (opnd->addr.offset.imm, 16))
2042
0
      {
2043
0
        set_unaligned_error (mismatch_detail, idx, 16);
2044
0
        return false;
2045
0
      }
2046
9.17k
    break;
2047
2048
20.8k
  case AARCH64_OPND_SIMD_ADDR_POST:
2049
    /* AdvSIMD load/store multiple structures, post-index.  */
2050
20.8k
    assert (idx == 1);
2051
20.8k
    if (opnd->addr.offset.is_reg)
2052
17.5k
      {
2053
17.5k
        if (value_in_range_p (opnd->addr.offset.regno, 0, 30))
2054
17.5k
    return true;
2055
0
        else
2056
0
    {
2057
0
      set_other_error (mismatch_detail, idx,
2058
0
           _("invalid register offset"));
2059
0
      return false;
2060
0
    }
2061
17.5k
      }
2062
3.25k
    else
2063
3.25k
      {
2064
3.25k
        const aarch64_opnd_info *prev = &opnds[idx-1];
2065
3.25k
        unsigned num_bytes; /* total number of bytes transferred.  */
2066
        /* The opcode dependent area stores the number of elements in
2067
     each structure to be loaded/stored.  */
2068
3.25k
        int is_ld1r = get_opcode_dependent_value (opcode) == 1;
2069
3.25k
        if (opcode->operands[0] == AARCH64_OPND_LVt_AL)
2070
    /* Special handling of loading single structure to all lane.  */
2071
664
    num_bytes = (is_ld1r ? 1 : prev->reglist.num_regs)
2072
664
      * aarch64_get_qualifier_esize (prev->qualifier);
2073
2.58k
        else
2074
2.58k
    num_bytes = prev->reglist.num_regs
2075
2.58k
      * aarch64_get_qualifier_esize (prev->qualifier)
2076
2.58k
      * aarch64_get_qualifier_nelem (prev->qualifier);
2077
3.25k
        if ((int) num_bytes != opnd->addr.offset.imm)
2078
0
    {
2079
0
      set_other_error (mismatch_detail, idx,
2080
0
           _("invalid post-increment amount"));
2081
0
      return false;
2082
0
    }
2083
3.25k
      }
2084
3.25k
    break;
2085
2086
63.4k
  case AARCH64_OPND_ADDR_REGOFF:
2087
    /* Get the size of the data element that is accessed, which may be
2088
       different from that of the source register size,
2089
       e.g. in strb/ldrb.  */
2090
63.4k
    size = aarch64_get_qualifier_esize (opnd->qualifier);
2091
    /* It is either no shift or shift by the binary logarithm of SIZE.  */
2092
63.4k
    if (opnd->shifter.amount != 0
2093
35.5k
        && opnd->shifter.amount != (int)get_logsz (size))
2094
0
      {
2095
0
        set_other_error (mismatch_detail, idx,
2096
0
             _("invalid shift amount"));
2097
0
        return false;
2098
0
      }
2099
    /* Only UXTW, LSL, SXTW and SXTX are the accepted extending
2100
       operators.  */
2101
63.4k
    switch (opnd->shifter.kind)
2102
63.4k
      {
2103
2.07k
      case AARCH64_MOD_UXTW:
2104
19.3k
      case AARCH64_MOD_LSL:
2105
22.1k
      case AARCH64_MOD_SXTW:
2106
27.1k
      case AARCH64_MOD_SXTX: break;
2107
36.3k
      default:
2108
36.3k
        set_other_error (mismatch_detail, idx,
2109
36.3k
             _("invalid extend/shift operator"));
2110
36.3k
        return false;
2111
63.4k
      }
2112
27.1k
    break;
2113
2114
247k
  case AARCH64_OPND_ADDR_UIMM12:
2115
247k
    imm = opnd->addr.offset.imm;
2116
    /* Get the size of the data element that is accessed, which may be
2117
       different from that of the source register size,
2118
       e.g. in strb/ldrb.  */
2119
247k
    size = aarch64_get_qualifier_esize (qualifier);
2120
247k
    if (!value_in_range_p (opnd->addr.offset.imm, 0, 4095 * size))
2121
0
      {
2122
0
        set_offset_out_of_range_error (mismatch_detail, idx,
2123
0
               0, 4095 * size);
2124
0
        return false;
2125
0
      }
2126
247k
    if (!value_aligned_p (opnd->addr.offset.imm, size))
2127
0
      {
2128
0
        set_unaligned_error (mismatch_detail, idx, size);
2129
0
        return false;
2130
0
      }
2131
247k
    break;
2132
2133
247k
  case AARCH64_OPND_ADDR_PCREL9:
2134
292k
  case AARCH64_OPND_ADDR_PCREL14:
2135
745k
  case AARCH64_OPND_ADDR_PCREL19:
2136
1.10M
  case AARCH64_OPND_ADDR_PCREL21:
2137
1.37M
  case AARCH64_OPND_ADDR_PCREL26:
2138
1.37M
    {
2139
1.37M
      imm = opnd->imm.value;
2140
1.37M
      if (operand_need_shift_by_two (get_operand_from_code (type)))
2141
1.01M
        {
2142
    /* The offset value in a PC-relative branch instruction is alway
2143
       4-byte aligned and is encoded without the lowest 2 bits.  */
2144
1.01M
    if (!value_aligned_p (imm, 4))
2145
0
      {
2146
0
        set_unaligned_error (mismatch_detail, idx, 4);
2147
0
        return false;
2148
0
      }
2149
    /* Right shift by 2 so that we can carry out the following check
2150
       canonically.  */
2151
1.01M
    imm >>= 2;
2152
1.01M
        }
2153
2154
1.37M
      if (!check_immediate_out_of_range (imm, type, mismatch_detail, idx))
2155
0
        return false;
2156
1.37M
    }
2157
1.37M
    break;
2158
2159
1.37M
  case AARCH64_OPND_SME_ADDR_RI_U4xVL:
2160
996
    if (!value_in_range_p (opnd->addr.offset.imm, 0, 15))
2161
0
      {
2162
0
        set_offset_out_of_range_error (mismatch_detail, idx, 0, 15);
2163
0
        return false;
2164
0
      }
2165
996
    break;
2166
2167
62.8k
  case AARCH64_OPND_SVE_ADDR_RI_S4xVL:
2168
75.3k
  case AARCH64_OPND_SVE_ADDR_RI_S4x2xVL:
2169
78.8k
  case AARCH64_OPND_SVE_ADDR_RI_S4x3xVL:
2170
86.3k
  case AARCH64_OPND_SVE_ADDR_RI_S4x4xVL:
2171
86.3k
    min_value = -8;
2172
86.3k
    max_value = 7;
2173
96.1k
  sve_imm_offset_vl:
2174
96.1k
    assert (!opnd->addr.offset.is_reg);
2175
96.1k
    assert (opnd->addr.preind);
2176
96.1k
    num = 1 + get_operand_specific_data (&aarch64_operands[type]);
2177
96.1k
    min_value *= num;
2178
96.1k
    max_value *= num;
2179
96.1k
    if ((opnd->addr.offset.imm != 0 && !opnd->shifter.operator_present)
2180
96.1k
        || (opnd->shifter.operator_present
2181
89.8k
      && opnd->shifter.kind != AARCH64_MOD_MUL_VL))
2182
0
      {
2183
0
        set_other_error (mismatch_detail, idx,
2184
0
             _("invalid addressing mode"));
2185
0
        return false;
2186
0
      }
2187
96.1k
    if (!value_in_range_p (opnd->addr.offset.imm, min_value, max_value))
2188
0
      {
2189
0
        set_offset_out_of_range_error (mismatch_detail, idx,
2190
0
               min_value, max_value);
2191
0
        return false;
2192
0
      }
2193
96.1k
    if (!value_aligned_p (opnd->addr.offset.imm, num))
2194
0
      {
2195
0
        set_unaligned_error (mismatch_detail, idx, num);
2196
0
        return false;
2197
0
      }
2198
96.1k
    break;
2199
2200
96.1k
  case AARCH64_OPND_SVE_ADDR_RI_S6xVL:
2201
3.25k
    min_value = -32;
2202
3.25k
    max_value = 31;
2203
3.25k
    goto sve_imm_offset_vl;
2204
2205
6.56k
  case AARCH64_OPND_SVE_ADDR_RI_S9xVL:
2206
6.56k
    min_value = -256;
2207
6.56k
    max_value = 255;
2208
6.56k
    goto sve_imm_offset_vl;
2209
2210
6.54k
  case AARCH64_OPND_SVE_ADDR_RI_U6:
2211
11.4k
  case AARCH64_OPND_SVE_ADDR_RI_U6x2:
2212
13.3k
  case AARCH64_OPND_SVE_ADDR_RI_U6x4:
2213
14.9k
  case AARCH64_OPND_SVE_ADDR_RI_U6x8:
2214
14.9k
    min_value = 0;
2215
14.9k
    max_value = 63;
2216
34.1k
  sve_imm_offset:
2217
34.1k
    assert (!opnd->addr.offset.is_reg);
2218
34.1k
    assert (opnd->addr.preind);
2219
34.1k
    num = 1 << get_operand_specific_data (&aarch64_operands[type]);
2220
34.1k
    min_value *= num;
2221
34.1k
    max_value *= num;
2222
34.1k
    if (opnd->shifter.operator_present
2223
34.1k
        || opnd->shifter.amount_present)
2224
0
      {
2225
0
        set_other_error (mismatch_detail, idx,
2226
0
             _("invalid addressing mode"));
2227
0
        return false;
2228
0
      }
2229
34.1k
    if (!value_in_range_p (opnd->addr.offset.imm, min_value, max_value))
2230
0
      {
2231
0
        set_offset_out_of_range_error (mismatch_detail, idx,
2232
0
               min_value, max_value);
2233
0
        return false;
2234
0
      }
2235
34.1k
    if (!value_aligned_p (opnd->addr.offset.imm, num))
2236
0
      {
2237
0
        set_unaligned_error (mismatch_detail, idx, num);
2238
0
        return false;
2239
0
      }
2240
34.1k
    break;
2241
2242
34.1k
  case AARCH64_OPND_SVE_ADDR_RI_S4x16:
2243
2.95k
  case AARCH64_OPND_SVE_ADDR_RI_S4x32:
2244
2.95k
    min_value = -8;
2245
2.95k
    max_value = 7;
2246
2.95k
    goto sve_imm_offset;
2247
2248
16.0k
  case AARCH64_OPND_SVE_ADDR_ZX:
2249
    /* Everything is already ensured by parse_operands or
2250
       aarch64_ext_sve_addr_rr_lsl (because this is a very specific
2251
       argument type).  */
2252
16.0k
    assert (opnd->addr.offset.is_reg);
2253
16.0k
    assert (opnd->addr.preind);
2254
16.0k
    assert ((aarch64_operands[type].flags & OPD_F_NO_ZR) == 0);
2255
16.0k
    assert (opnd->shifter.kind == AARCH64_MOD_LSL);
2256
16.0k
    assert (opnd->shifter.operator_present == 0);
2257
16.0k
    break;
2258
2259
16.0k
  case AARCH64_OPND_SVE_ADDR_RR:
2260
20.5k
  case AARCH64_OPND_SVE_ADDR_RR_LSL1:
2261
25.6k
  case AARCH64_OPND_SVE_ADDR_RR_LSL2:
2262
42.4k
  case AARCH64_OPND_SVE_ADDR_RR_LSL3:
2263
58.6k
  case AARCH64_OPND_SVE_ADDR_RR_LSL4:
2264
68.5k
  case AARCH64_OPND_SVE_ADDR_RM:
2265
72.9k
  case AARCH64_OPND_SVE_ADDR_RM_LSL1:
2266
77.5k
  case AARCH64_OPND_SVE_ADDR_RM_LSL2:
2267
81.2k
  case AARCH64_OPND_SVE_ADDR_RM_LSL3:
2268
81.2k
  case AARCH64_OPND_SVE_ADDR_RM_LSL4:
2269
99.0k
  case AARCH64_OPND_SVE_ADDR_RX:
2270
109k
  case AARCH64_OPND_SVE_ADDR_RX_LSL1:
2271
120k
  case AARCH64_OPND_SVE_ADDR_RX_LSL2:
2272
125k
  case AARCH64_OPND_SVE_ADDR_RX_LSL3:
2273
129k
  case AARCH64_OPND_SVE_ADDR_RX_LSL4:
2274
152k
  case AARCH64_OPND_SVE_ADDR_RZ:
2275
155k
  case AARCH64_OPND_SVE_ADDR_RZ_LSL1:
2276
158k
  case AARCH64_OPND_SVE_ADDR_RZ_LSL2:
2277
161k
  case AARCH64_OPND_SVE_ADDR_RZ_LSL3:
2278
161k
    modifiers = 1 << AARCH64_MOD_LSL;
2279
236k
  sve_rr_operand:
2280
236k
    assert (opnd->addr.offset.is_reg);
2281
236k
    assert (opnd->addr.preind);
2282
236k
    if ((aarch64_operands[type].flags & OPD_F_NO_ZR) != 0
2283
48.7k
        && opnd->addr.offset.regno == 31)
2284
0
      {
2285
0
        set_other_error (mismatch_detail, idx,
2286
0
             _("index register xzr is not allowed"));
2287
0
        return false;
2288
0
      }
2289
236k
    if (((1 << opnd->shifter.kind) & modifiers) == 0
2290
236k
        || (opnd->shifter.amount
2291
236k
      != get_operand_specific_data (&aarch64_operands[type])))
2292
0
      {
2293
0
        set_other_error (mismatch_detail, idx,
2294
0
             _("invalid addressing mode"));
2295
0
        return false;
2296
0
      }
2297
236k
    break;
2298
2299
236k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW_14:
2300
47.4k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW_22:
2301
49.3k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW1_14:
2302
57.6k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW1_22:
2303
59.0k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW2_14:
2304
66.5k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW2_22:
2305
67.0k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW3_14:
2306
75.0k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW3_22:
2307
75.0k
    modifiers = (1 << AARCH64_MOD_SXTW) | (1 << AARCH64_MOD_UXTW);
2308
75.0k
    goto sve_rr_operand;
2309
2310
5.18k
  case AARCH64_OPND_SVE_ADDR_ZI_U5:
2311
11.7k
  case AARCH64_OPND_SVE_ADDR_ZI_U5x2:
2312
14.7k
  case AARCH64_OPND_SVE_ADDR_ZI_U5x4:
2313
16.2k
  case AARCH64_OPND_SVE_ADDR_ZI_U5x8:
2314
16.2k
    min_value = 0;
2315
16.2k
    max_value = 31;
2316
16.2k
    goto sve_imm_offset;
2317
2318
1.00k
  case AARCH64_OPND_SVE_ADDR_ZZ_LSL:
2319
1.00k
    modifiers = 1 << AARCH64_MOD_LSL;
2320
2.23k
  sve_zz_operand:
2321
2.23k
    assert (opnd->addr.offset.is_reg);
2322
2.23k
    assert (opnd->addr.preind);
2323
2.23k
    if (((1 << opnd->shifter.kind) & modifiers) == 0
2324
2.23k
        || opnd->shifter.amount < 0
2325
2.23k
        || opnd->shifter.amount > 3)
2326
0
      {
2327
0
        set_other_error (mismatch_detail, idx,
2328
0
             _("invalid addressing mode"));
2329
0
        return false;
2330
0
      }
2331
2.23k
    break;
2332
2333
2.23k
  case AARCH64_OPND_SVE_ADDR_ZZ_SXTW:
2334
294
    modifiers = (1 << AARCH64_MOD_SXTW);
2335
294
    goto sve_zz_operand;
2336
2337
942
  case AARCH64_OPND_SVE_ADDR_ZZ_UXTW:
2338
942
    modifiers = 1 << AARCH64_MOD_UXTW;
2339
942
    goto sve_zz_operand;
2340
2341
15.7k
  case AARCH64_OPND_RCPC3_ADDR_OPT_PREIND_WB:
2342
16.6k
  case AARCH64_OPND_RCPC3_ADDR_OPT_POSTIND:
2343
16.9k
  case AARCH64_OPND_RCPC3_ADDR_PREIND_WB:
2344
17.0k
  case AARCH64_OPND_RCPC3_ADDR_POSTIND:
2345
17.0k
    {
2346
17.0k
      int num_bytes = calc_ldst_datasize (opnds);
2347
17.0k
      int abs_offset = (type == AARCH64_OPND_RCPC3_ADDR_OPT_PREIND_WB
2348
1.29k
            || type == AARCH64_OPND_RCPC3_ADDR_PREIND_WB)
2349
17.0k
        ? opnd->addr.offset.imm * -1
2350
17.0k
        : opnd->addr.offset.imm;
2351
17.0k
      if ((int) num_bytes != abs_offset
2352
15.2k
    && opnd->addr.offset.imm != 0)
2353
0
        {
2354
0
    set_other_error (mismatch_detail, idx,
2355
0
         _("invalid increment amount"));
2356
0
    return false;
2357
0
        }
2358
17.0k
    }
2359
17.0k
    break;
2360
2361
17.0k
  case AARCH64_OPND_RCPC3_ADDR_OFFSET:
2362
7.36k
    if (!value_in_range_p (opnd->addr.offset.imm, -256, 255))
2363
0
      {
2364
0
        set_imm_out_of_range_error (mismatch_detail, idx, -256, 255);
2365
0
        return false;
2366
0
      }
2367
2368
448k
  default:
2369
448k
    break;
2370
3.30M
  }
2371
3.25M
      break;
2372
2373
3.25M
    case AARCH64_OPND_CLASS_SIMD_REGLIST:
2374
59.8k
      if (type == AARCH64_OPND_LEt)
2375
20.8k
  {
2376
    /* Get the upper bound for the element index.  */
2377
20.8k
    num = 16 / aarch64_get_qualifier_esize (qualifier) - 1;
2378
20.8k
    if (!value_in_range_p (opnd->reglist.index, 0, num))
2379
0
      {
2380
0
        set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, num);
2381
0
        return false;
2382
0
      }
2383
20.8k
  }
2384
      /* The opcode dependent area stores the number of elements in
2385
   each structure to be loaded/stored.  */
2386
59.8k
      num = get_opcode_dependent_value (opcode);
2387
59.8k
      switch (type)
2388
59.8k
  {
2389
4.76k
  case AARCH64_OPND_LVn_LUT:
2390
4.76k
    if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
2391
0
      return 0;
2392
4.76k
    break;
2393
15.1k
  case AARCH64_OPND_LVt:
2394
15.1k
    assert (num >= 1 && num <= 4);
2395
    /* Unless LD1/ST1, the number of registers should be equal to that
2396
       of the structure elements.  */
2397
15.1k
    if (num != 1 && !check_reglist (opnd, mismatch_detail, idx, num, 1))
2398
787
      return false;
2399
14.4k
    break;
2400
14.4k
  case AARCH64_OPND_LVt_AL:
2401
22.8k
  case AARCH64_OPND_LEt:
2402
22.8k
    assert (num >= 1 && num <= 4);
2403
    /* The number of registers should be equal to that of the structure
2404
       elements.  */
2405
22.8k
    if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
2406
0
      return false;
2407
22.8k
    break;
2408
22.8k
  default:
2409
17.0k
    break;
2410
59.8k
  }
2411
59.0k
      if (opnd->reglist.stride != 1)
2412
0
  {
2413
0
    set_reg_list_stride_error (mismatch_detail, idx, 1);
2414
0
    return false;
2415
0
  }
2416
59.0k
      break;
2417
2418
3.51M
    case AARCH64_OPND_CLASS_IMMEDIATE:
2419
      /* Constraint check on immediate operand.  */
2420
3.51M
      imm = opnd->imm.value;
2421
      /* E.g. imm_0_31 constrains value to be 0..31.  */
2422
3.51M
      if (qualifier_value_in_range_constraint_p (qualifier)
2423
457k
    && !value_in_range_p (imm, get_lower_bound (qualifier),
2424
457k
        get_upper_bound (qualifier)))
2425
49.6k
  {
2426
49.6k
    set_imm_out_of_range_error (mismatch_detail, idx,
2427
49.6k
              get_lower_bound (qualifier),
2428
49.6k
              get_upper_bound (qualifier));
2429
49.6k
    return false;
2430
49.6k
  }
2431
2432
3.46M
      switch (type)
2433
3.46M
  {
2434
439k
  case AARCH64_OPND_AIMM:
2435
439k
    if (opnd->shifter.kind != AARCH64_MOD_LSL)
2436
0
      {
2437
0
        set_other_error (mismatch_detail, idx,
2438
0
             _("invalid shift operator"));
2439
0
        return false;
2440
0
      }
2441
439k
    if (opnd->shifter.amount != 0 && opnd->shifter.amount != 12)
2442
0
      {
2443
0
        set_other_error (mismatch_detail, idx,
2444
0
             _("shift amount must be 0 or 12"));
2445
0
        return false;
2446
0
      }
2447
439k
    if (!value_fit_unsigned_field_p (opnd->imm.value, 12))
2448
0
      {
2449
0
        set_other_error (mismatch_detail, idx,
2450
0
             _("immediate out of range"));
2451
0
        return false;
2452
0
      }
2453
439k
    break;
2454
2455
439k
  case AARCH64_OPND_HALF:
2456
113k
    assert (idx == 1 && opnds[0].type == AARCH64_OPND_Rd);
2457
113k
    if (opnd->shifter.kind != AARCH64_MOD_LSL)
2458
0
      {
2459
0
        set_other_error (mismatch_detail, idx,
2460
0
             _("invalid shift operator"));
2461
0
        return false;
2462
0
      }
2463
113k
    size = aarch64_get_qualifier_esize (opnds[0].qualifier);
2464
113k
    if (!value_aligned_p (opnd->shifter.amount, 16))
2465
0
      {
2466
0
        set_other_error (mismatch_detail, idx,
2467
0
             _("shift amount must be a multiple of 16"));
2468
0
        return false;
2469
0
      }
2470
113k
    if (!value_in_range_p (opnd->shifter.amount, 0, size * 8 - 16))
2471
19.3k
      {
2472
19.3k
        set_sft_amount_out_of_range_error (mismatch_detail, idx,
2473
19.3k
             0, size * 8 - 16);
2474
19.3k
        return false;
2475
19.3k
      }
2476
94.6k
    if (opnd->imm.value < 0)
2477
0
      {
2478
0
        set_other_error (mismatch_detail, idx,
2479
0
             _("negative immediate value not allowed"));
2480
0
        return false;
2481
0
      }
2482
94.6k
    if (!value_fit_unsigned_field_p (opnd->imm.value, 16))
2483
0
      {
2484
0
        set_other_error (mismatch_detail, idx,
2485
0
             _("immediate out of range"));
2486
0
        return false;
2487
0
      }
2488
94.6k
    break;
2489
2490
94.6k
  case AARCH64_OPND_IMM_MOV:
2491
66.2k
      {
2492
66.2k
        int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
2493
66.2k
        imm = opnd->imm.value;
2494
66.2k
        assert (idx == 1);
2495
66.2k
        switch (opcode->op)
2496
66.2k
    {
2497
30.1k
    case OP_MOV_IMM_WIDEN:
2498
30.1k
      imm = ~imm;
2499
      /* Fall through.  */
2500
65.3k
    case OP_MOV_IMM_WIDE:
2501
65.3k
      if (!aarch64_wide_constant_p (imm, esize == 4, NULL))
2502
0
        {
2503
0
          set_other_error (mismatch_detail, idx,
2504
0
               _("immediate out of range"));
2505
0
          return false;
2506
0
        }
2507
65.3k
      break;
2508
65.3k
    case OP_MOV_IMM_LOG:
2509
887
      if (!aarch64_logical_immediate_p (imm, esize, NULL))
2510
0
        {
2511
0
          set_other_error (mismatch_detail, idx,
2512
0
               _("immediate out of range"));
2513
0
          return false;
2514
0
        }
2515
887
      break;
2516
887
    default:
2517
0
      assert (0);
2518
0
      return false;
2519
66.2k
    }
2520
66.2k
      }
2521
66.2k
    break;
2522
2523
66.2k
  case AARCH64_OPND_NZCV:
2524
11.3k
  case AARCH64_OPND_CCMP_IMM:
2525
12.8k
  case AARCH64_OPND_EXCEPTION:
2526
1.86M
  case AARCH64_OPND_UNDEFINED:
2527
1.86M
  case AARCH64_OPND_TME_UIMM16:
2528
1.86M
  case AARCH64_OPND_UIMM4:
2529
1.87M
  case AARCH64_OPND_UIMM4_ADDG:
2530
1.87M
  case AARCH64_OPND_UIMM7:
2531
1.88M
  case AARCH64_OPND_UIMM3_OP1:
2532
1.89M
  case AARCH64_OPND_UIMM3_OP2:
2533
1.89M
  case AARCH64_OPND_SVE_UIMM3:
2534
1.92M
  case AARCH64_OPND_SVE_UIMM7:
2535
1.93M
  case AARCH64_OPND_SVE_UIMM8:
2536
1.93M
  case AARCH64_OPND_SVE_UIMM4:
2537
1.93M
  case AARCH64_OPND_SVE_UIMM8_53:
2538
1.93M
  case AARCH64_OPND_CSSC_UIMM8:
2539
1.93M
    size = get_operand_fields_width (get_operand_from_code (type));
2540
1.93M
    assert (size < 32);
2541
1.93M
    if (!value_fit_unsigned_field_p (opnd->imm.value, size))
2542
0
      {
2543
0
        set_imm_out_of_range_error (mismatch_detail, idx, 0,
2544
0
            (1u << size) - 1);
2545
0
        return false;
2546
0
      }
2547
1.93M
    break;
2548
2549
1.93M
  case AARCH64_OPND_UIMM10:
2550
    /* Scaled unsigned 10 bits immediate offset.  */
2551
4.89k
    if (!value_in_range_p (opnd->imm.value, 0, 1008))
2552
0
      {
2553
0
        set_imm_out_of_range_error (mismatch_detail, idx, 0, 1008);
2554
0
        return false;
2555
0
      }
2556
2557
4.89k
    if (!value_aligned_p (opnd->imm.value, 16))
2558
0
      {
2559
0
        set_unaligned_error (mismatch_detail, idx, 16);
2560
0
        return false;
2561
0
      }
2562
4.89k
    break;
2563
2564
14.4k
  case AARCH64_OPND_SIMM5:
2565
15.0k
  case AARCH64_OPND_SVE_SIMM5:
2566
15.4k
  case AARCH64_OPND_SVE_SIMM5B:
2567
16.2k
  case AARCH64_OPND_SVE_SIMM6:
2568
16.7k
  case AARCH64_OPND_SVE_SIMM8:
2569
18.4k
  case AARCH64_OPND_CSSC_SIMM8:
2570
18.4k
    size = get_operand_fields_width (get_operand_from_code (type));
2571
18.4k
    assert (size < 32);
2572
18.4k
    if (!value_fit_signed_field_p (opnd->imm.value, size))
2573
0
      {
2574
0
        imm_range_t rng = imm_range_min_max (size, true);
2575
0
        set_imm_out_of_range_error (mismatch_detail, idx, rng.min,
2576
0
            rng.max);
2577
0
        return false;
2578
0
      }
2579
18.4k
    break;
2580
2581
35.4k
  case AARCH64_OPND_WIDTH:
2582
35.4k
    assert (idx > 1 && opnds[idx-1].type == AARCH64_OPND_IMM
2583
35.4k
      && opnds[0].type == AARCH64_OPND_Rd);
2584
35.4k
    size = get_upper_bound (qualifier);
2585
35.4k
    if (opnd->imm.value + opnds[idx-1].imm.value > size)
2586
      /* lsb+width <= reg.size  */
2587
0
      {
2588
0
        set_imm_out_of_range_error (mismatch_detail, idx, 1,
2589
0
            size - opnds[idx-1].imm.value);
2590
0
        return false;
2591
0
      }
2592
35.4k
    break;
2593
2594
307k
  case AARCH64_OPND_LIMM:
2595
351k
  case AARCH64_OPND_SVE_LIMM:
2596
351k
    {
2597
351k
      int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
2598
351k
      uint64_t uimm = opnd->imm.value;
2599
351k
      if (opcode->op == OP_BIC)
2600
0
        uimm = ~uimm;
2601
351k
      if (!aarch64_logical_immediate_p (uimm, esize, NULL))
2602
0
        {
2603
0
    set_other_error (mismatch_detail, idx,
2604
0
         _("immediate out of range"));
2605
0
    return false;
2606
0
        }
2607
351k
    }
2608
351k
    break;
2609
2610
351k
  case AARCH64_OPND_IMM0:
2611
660
  case AARCH64_OPND_FPIMM0:
2612
660
    if (opnd->imm.value != 0)
2613
0
      {
2614
0
        set_other_error (mismatch_detail, idx,
2615
0
             _("immediate zero expected"));
2616
0
        return false;
2617
0
      }
2618
660
    break;
2619
2620
761
  case AARCH64_OPND_IMM_ROT1:
2621
18.2k
  case AARCH64_OPND_IMM_ROT2:
2622
27.6k
  case AARCH64_OPND_SVE_IMM_ROT2:
2623
27.6k
    if (opnd->imm.value != 0
2624
20.1k
        && opnd->imm.value != 90
2625
12.7k
        && opnd->imm.value != 180
2626
8.36k
        && opnd->imm.value != 270)
2627
0
      {
2628
0
        set_other_error (mismatch_detail, idx,
2629
0
             _("rotate expected to be 0, 90, 180 or 270"));
2630
0
        return false;
2631
0
      }
2632
27.6k
    break;
2633
2634
27.6k
  case AARCH64_OPND_IMM_ROT3:
2635
1.30k
  case AARCH64_OPND_SVE_IMM_ROT1:
2636
1.74k
  case AARCH64_OPND_SVE_IMM_ROT3:
2637
1.74k
    if (opnd->imm.value != 90 && opnd->imm.value != 270)
2638
0
      {
2639
0
        set_other_error (mismatch_detail, idx,
2640
0
             _("rotate expected to be 90 or 270"));
2641
0
        return false;
2642
0
      }
2643
1.74k
    break;
2644
2645
1.74k
  case AARCH64_OPND_SHLL_IMM:
2646
245
    assert (idx == 2);
2647
245
    size = 8 * aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
2648
245
    if (opnd->imm.value != size)
2649
0
      {
2650
0
        set_other_error (mismatch_detail, idx,
2651
0
             _("invalid shift amount"));
2652
0
        return false;
2653
0
      }
2654
245
    break;
2655
2656
9.01k
  case AARCH64_OPND_IMM_VLSL:
2657
9.01k
    size = aarch64_get_qualifier_esize (qualifier);
2658
9.01k
    if (!value_in_range_p (opnd->imm.value, 0, size * 8 - 1))
2659
0
      {
2660
0
        set_imm_out_of_range_error (mismatch_detail, idx, 0,
2661
0
            size * 8 - 1);
2662
0
        return false;
2663
0
      }
2664
9.01k
    break;
2665
2666
14.3k
  case AARCH64_OPND_IMM_VLSR:
2667
14.3k
    size = aarch64_get_qualifier_esize (qualifier);
2668
14.3k
    if (!value_in_range_p (opnd->imm.value, 1, size * 8))
2669
0
      {
2670
0
        set_imm_out_of_range_error (mismatch_detail, idx, 1, size * 8);
2671
0
        return false;
2672
0
      }
2673
14.3k
    break;
2674
2675
14.3k
  case AARCH64_OPND_SIMD_IMM:
2676
4.21k
  case AARCH64_OPND_SIMD_IMM_SFT:
2677
    /* Qualifier check.  */
2678
4.21k
    switch (qualifier)
2679
4.21k
      {
2680
3.10k
      case AARCH64_OPND_QLF_LSL:
2681
3.10k
        if (opnd->shifter.kind != AARCH64_MOD_LSL)
2682
0
    {
2683
0
      set_other_error (mismatch_detail, idx,
2684
0
           _("invalid shift operator"));
2685
0
      return false;
2686
0
    }
2687
3.10k
        break;
2688
3.10k
      case AARCH64_OPND_QLF_MSL:
2689
381
        if (opnd->shifter.kind != AARCH64_MOD_MSL)
2690
0
    {
2691
0
      set_other_error (mismatch_detail, idx,
2692
0
           _("invalid shift operator"));
2693
0
      return false;
2694
0
    }
2695
381
        break;
2696
725
      case AARCH64_OPND_QLF_NIL:
2697
725
        if (opnd->shifter.kind != AARCH64_MOD_NONE)
2698
0
    {
2699
0
      set_other_error (mismatch_detail, idx,
2700
0
           _("shift is not permitted"));
2701
0
      return false;
2702
0
    }
2703
725
        break;
2704
725
      default:
2705
0
        assert (0);
2706
0
        return false;
2707
4.21k
      }
2708
    /* Is the immediate valid?  */
2709
4.21k
    assert (idx == 1);
2710
4.21k
    if (aarch64_get_qualifier_esize (opnds[0].qualifier) != 8)
2711
3.48k
      {
2712
        /* uimm8 or simm8 */
2713
3.48k
        if (!value_in_range_p (opnd->imm.value, -128, 255))
2714
0
    {
2715
0
      set_imm_out_of_range_error (mismatch_detail, idx, -128, 255);
2716
0
      return false;
2717
0
    }
2718
3.48k
      }
2719
725
    else if (aarch64_shrink_expanded_imm8 (opnd->imm.value) < 0)
2720
0
      {
2721
        /* uimm64 is not
2722
     'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeee
2723
     ffffffffgggggggghhhhhhhh'.  */
2724
0
        set_other_error (mismatch_detail, idx,
2725
0
             _("invalid value for immediate"));
2726
0
        return false;
2727
0
      }
2728
    /* Is the shift amount valid?  */
2729
4.21k
    switch (opnd->shifter.kind)
2730
4.21k
      {
2731
3.10k
      case AARCH64_MOD_LSL:
2732
3.10k
        size = aarch64_get_qualifier_esize (opnds[0].qualifier);
2733
3.10k
        if (!value_in_range_p (opnd->shifter.amount, 0, (size - 1) * 8))
2734
0
    {
2735
0
      set_sft_amount_out_of_range_error (mismatch_detail, idx, 0,
2736
0
                 (size - 1) * 8);
2737
0
      return false;
2738
0
    }
2739
3.10k
        if (!value_aligned_p (opnd->shifter.amount, 8))
2740
0
    {
2741
0
      set_unaligned_error (mismatch_detail, idx, 8);
2742
0
      return false;
2743
0
    }
2744
3.10k
        break;
2745
3.10k
      case AARCH64_MOD_MSL:
2746
        /* Only 8 and 16 are valid shift amount.  */
2747
381
        if (opnd->shifter.amount != 8 && opnd->shifter.amount != 16)
2748
0
    {
2749
0
      set_other_error (mismatch_detail, idx,
2750
0
           _("shift amount must be 0 or 16"));
2751
0
      return false;
2752
0
    }
2753
381
        break;
2754
725
      default:
2755
725
        if (opnd->shifter.kind != AARCH64_MOD_NONE)
2756
0
    {
2757
0
      set_other_error (mismatch_detail, idx,
2758
0
           _("invalid shift operator"));
2759
0
      return false;
2760
0
    }
2761
725
        break;
2762
4.21k
      }
2763
4.21k
    break;
2764
2765
4.21k
  case AARCH64_OPND_FPIMM:
2766
2.49k
  case AARCH64_OPND_SIMD_FPIMM:
2767
4.50k
  case AARCH64_OPND_SVE_FPIMM8:
2768
4.50k
    if (opnd->imm.is_fp == 0)
2769
0
      {
2770
0
        set_other_error (mismatch_detail, idx,
2771
0
             _("floating-point immediate expected"));
2772
0
        return false;
2773
0
      }
2774
    /* The value is expected to be an 8-bit floating-point constant with
2775
       sign, 3-bit exponent and normalized 4 bits of precision, encoded
2776
       in "a:b:c:d:e:f:g:h" or FLD_imm8 (depending on the type of the
2777
       instruction).  */
2778
4.50k
    if (!value_in_range_p (opnd->imm.value, 0, 255))
2779
0
      {
2780
0
        set_other_error (mismatch_detail, idx,
2781
0
             _("immediate out of range"));
2782
0
        return false;
2783
0
      }
2784
4.50k
    if (opnd->shifter.kind != AARCH64_MOD_NONE)
2785
0
      {
2786
0
        set_other_error (mismatch_detail, idx,
2787
0
             _("invalid shift operator"));
2788
0
        return false;
2789
0
      }
2790
4.50k
    break;
2791
2792
4.50k
  case AARCH64_OPND_SVE_AIMM:
2793
2.72k
    min_value = 0;
2794
20.5k
  sve_aimm:
2795
20.5k
    assert (opnd->shifter.kind == AARCH64_MOD_LSL);
2796
20.5k
    size = aarch64_get_qualifier_esize (opnds[0].qualifier);
2797
20.5k
    mask = ~((uint64_t) -1 << (size * 4) << (size * 4));
2798
20.5k
    uvalue = opnd->imm.value;
2799
20.5k
    shift = opnd->shifter.amount;
2800
20.5k
    if (size == 1)
2801
4.29k
      {
2802
4.29k
        if (shift != 0)
2803
151
    {
2804
151
      set_other_error (mismatch_detail, idx,
2805
151
           _("no shift amount allowed for"
2806
151
             " 8-bit constants"));
2807
151
      return false;
2808
151
    }
2809
4.29k
      }
2810
16.2k
    else
2811
16.2k
      {
2812
16.2k
        if (shift != 0 && shift != 8)
2813
0
    {
2814
0
      set_other_error (mismatch_detail, idx,
2815
0
           _("shift amount must be 0 or 8"));
2816
0
      return false;
2817
0
    }
2818
16.2k
        if (shift == 0 && (uvalue & 0xff) == 0)
2819
6.31k
    {
2820
6.31k
      shift = 8;
2821
6.31k
      uvalue = (int64_t) uvalue / 256;
2822
6.31k
    }
2823
16.2k
      }
2824
20.3k
    mask >>= shift;
2825
20.3k
    if ((uvalue & mask) != uvalue && (uvalue | ~mask) != uvalue)
2826
1.73k
      {
2827
1.73k
        set_other_error (mismatch_detail, idx,
2828
1.73k
             _("immediate too big for element size"));
2829
1.73k
        return false;
2830
1.73k
      }
2831
18.6k
    uvalue = (uvalue - min_value) & mask;
2832
18.6k
    if (uvalue > 0xff)
2833
0
      {
2834
0
        set_other_error (mismatch_detail, idx,
2835
0
             _("invalid arithmetic immediate"));
2836
0
        return false;
2837
0
      }
2838
18.6k
    break;
2839
2840
18.6k
  case AARCH64_OPND_SVE_ASIMM:
2841
17.8k
    min_value = -128;
2842
17.8k
    goto sve_aimm;
2843
2844
79
  case AARCH64_OPND_SVE_I1_HALF_ONE:
2845
79
    assert (opnd->imm.is_fp);
2846
79
    if (opnd->imm.value != 0x3f000000 && opnd->imm.value != 0x3f800000)
2847
0
      {
2848
0
        set_other_error (mismatch_detail, idx,
2849
0
             _("floating-point value must be 0.5 or 1.0"));
2850
0
        return false;
2851
0
      }
2852
79
    break;
2853
2854
285
  case AARCH64_OPND_SVE_I1_HALF_TWO:
2855
285
    assert (opnd->imm.is_fp);
2856
285
    if (opnd->imm.value != 0x3f000000 && opnd->imm.value != 0x40000000)
2857
0
      {
2858
0
        set_other_error (mismatch_detail, idx,
2859
0
             _("floating-point value must be 0.5 or 2.0"));
2860
0
        return false;
2861
0
      }
2862
285
    break;
2863
2864
1.21k
  case AARCH64_OPND_SVE_I1_ZERO_ONE:
2865
1.21k
    assert (opnd->imm.is_fp);
2866
1.21k
    if (opnd->imm.value != 0 && opnd->imm.value != 0x3f800000)
2867
0
      {
2868
0
        set_other_error (mismatch_detail, idx,
2869
0
             _("floating-point value must be 0.0 or 1.0"));
2870
0
        return false;
2871
0
      }
2872
1.21k
    break;
2873
2874
1.21k
  case AARCH64_OPND_SVE_INV_LIMM:
2875
0
    {
2876
0
      int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
2877
0
      uint64_t uimm = ~opnd->imm.value;
2878
0
      if (!aarch64_logical_immediate_p (uimm, esize, NULL))
2879
0
        {
2880
0
    set_other_error (mismatch_detail, idx,
2881
0
         _("immediate out of range"));
2882
0
    return false;
2883
0
        }
2884
0
    }
2885
0
    break;
2886
2887
3.48k
  case AARCH64_OPND_SVE_LIMM_MOV:
2888
3.48k
    {
2889
3.48k
      int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
2890
3.48k
      uint64_t uimm = opnd->imm.value;
2891
3.48k
      if (!aarch64_logical_immediate_p (uimm, esize, NULL))
2892
0
        {
2893
0
    set_other_error (mismatch_detail, idx,
2894
0
         _("immediate out of range"));
2895
0
    return false;
2896
0
        }
2897
3.48k
      if (!aarch64_sve_dupm_mov_immediate_p (uimm, esize))
2898
0
        {
2899
0
    set_other_error (mismatch_detail, idx,
2900
0
         _("invalid replicated MOV immediate"));
2901
0
    return false;
2902
0
        }
2903
3.48k
    }
2904
3.48k
    break;
2905
2906
7.12k
  case AARCH64_OPND_SVE_PATTERN_SCALED:
2907
7.12k
    assert (opnd->shifter.kind == AARCH64_MOD_MUL);
2908
7.12k
    if (!value_in_range_p (opnd->shifter.amount, 1, 16))
2909
0
      {
2910
0
        set_multiplier_out_of_range_error (mismatch_detail, idx, 1, 16);
2911
0
        return false;
2912
0
      }
2913
7.12k
    break;
2914
2915
7.12k
  case AARCH64_OPND_SVE_SHLIMM_PRED:
2916
2.50k
  case AARCH64_OPND_SVE_SHLIMM_UNPRED:
2917
3.57k
  case AARCH64_OPND_SVE_SHLIMM_UNPRED_22:
2918
3.57k
    size = aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
2919
3.57k
    if (!value_in_range_p (opnd->imm.value, 0, 8 * size - 1))
2920
0
      {
2921
0
        set_imm_out_of_range_error (mismatch_detail, idx,
2922
0
            0, 8 * size - 1);
2923
0
        return false;
2924
0
      }
2925
3.57k
    break;
2926
2927
3.57k
  case AARCH64_OPND_SME_SHRIMM3:
2928
465
  case AARCH64_OPND_SME_SHRIMM4:
2929
465
    size = 1 << get_operand_fields_width (get_operand_from_code (type));
2930
465
    if (!value_in_range_p (opnd->imm.value, 1, size))
2931
0
      {
2932
0
        set_imm_out_of_range_error (mismatch_detail, idx, 1, size);
2933
0
        return false;
2934
0
      }
2935
465
    break;
2936
2937
465
  case AARCH64_OPND_SME_SHRIMM5:
2938
1.86k
  case AARCH64_OPND_SVE_SHRIMM_PRED:
2939
4.39k
  case AARCH64_OPND_SVE_SHRIMM_UNPRED:
2940
9.35k
  case AARCH64_OPND_SVE_SHRIMM_UNPRED_22:
2941
9.35k
    num = (type == AARCH64_OPND_SVE_SHRIMM_UNPRED_22) ? 2 : 1;
2942
9.35k
    size = aarch64_get_qualifier_esize (opnds[idx - num].qualifier);
2943
9.35k
    if (!value_in_range_p (opnd->imm.value, 1, 8 * size))
2944
0
      {
2945
0
        set_imm_out_of_range_error (mismatch_detail, idx, 1, 8*size);
2946
0
        return false;
2947
0
      }
2948
9.35k
    break;
2949
2950
9.35k
  case AARCH64_OPND_SME_ZT0_INDEX:
2951
120
    if (!value_in_range_p (opnd->imm.value, 0, 56))
2952
0
      {
2953
0
        set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, 56);
2954
0
        return false;
2955
0
      }
2956
120
    if (opnd->imm.value % 8 != 0)
2957
0
      {
2958
0
        set_other_error (mismatch_detail, idx,
2959
0
             _("byte index must be a multiple of 8"));
2960
0
        return false;
2961
0
      }
2962
120
    break;
2963
2964
162
  case AARCH64_OPND_SME_ZT0_INDEX_MUL_VL:
2965
162
    if (!value_in_range_p (opnd->imm.value, 0, 3))
2966
0
      {
2967
0
        set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, 3);
2968
0
        return 0;
2969
0
      }
2970
162
    break;
2971
2972
391k
  default:
2973
391k
    break;
2974
3.46M
  }
2975
3.44M
      break;
2976
2977
3.44M
    case AARCH64_OPND_CLASS_SYSTEM:
2978
66.6k
      switch (type)
2979
66.6k
  {
2980
244
  case AARCH64_OPND_PSTATEFIELD:
2981
805
    for (i = 0; aarch64_pstatefields[i].name; ++i)
2982
805
      if (aarch64_pstatefields[i].value == opnd->pstatefield)
2983
244
        break;
2984
244
    assert (aarch64_pstatefields[i].name);
2985
244
    assert (idx == 0 && opnds[1].type == AARCH64_OPND_UIMM4);
2986
244
    max_value = F_GET_REG_MAX_VALUE (aarch64_pstatefields[i].flags);
2987
244
    if (opnds[1].imm.value < 0 || opnds[1].imm.value > max_value)
2988
54
      {
2989
54
        set_imm_out_of_range_error (mismatch_detail, 1, 0, max_value);
2990
54
        return false;
2991
54
      }
2992
190
    break;
2993
46.5k
  case AARCH64_OPND_PRFOP:
2994
46.5k
    if (opcode->iclass == ldst_regoff && opnd->prfop->value >= 24)
2995
949
      {
2996
949
        set_other_error (mismatch_detail, idx,
2997
949
             _("the register-index form of PRFM does"
2998
949
         " not accept opcodes in the range 24-31"));
2999
949
        return false;
3000
949
      }
3001
45.5k
    break;
3002
45.5k
  default:
3003
19.8k
    break;
3004
66.6k
  }
3005
65.6k
      break;
3006
3007
105k
    case AARCH64_OPND_CLASS_SIMD_ELEMENT:
3008
      /* Get the upper bound for the element index.  */
3009
105k
      if (opcode->op == OP_FCMLA_ELEM)
3010
  /* FCMLA index range depends on the vector size of other operands
3011
     and is halfed because complex numbers take two elements.  */
3012
7.35k
  num = aarch64_get_qualifier_nelem (opnds[0].qualifier)
3013
7.35k
        * aarch64_get_qualifier_esize (opnds[0].qualifier) / 2;
3014
98.1k
      else if (opcode->iclass == lut)
3015
4.76k
  {
3016
4.76k
    size = get_operand_fields_width (get_operand_from_code (type)) - 5;
3017
4.76k
    if (!check_reglane (opnd, mismatch_detail, idx, "v", 0, 31,
3018
4.76k
            0, (1 << size) - 1))
3019
0
      return 0;
3020
4.76k
    break;
3021
4.76k
  }
3022
93.4k
      else
3023
93.4k
  num = 16;
3024
100k
      num = num / aarch64_get_qualifier_esize (qualifier) - 1;
3025
100k
      assert (aarch64_get_qualifier_nelem (qualifier) == 1);
3026
3027
      /* Index out-of-range.  */
3028
100k
      if (!value_in_range_p (opnd->reglane.index, 0, num))
3029
645
  {
3030
645
    set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, num);
3031
645
    return false;
3032
645
  }
3033
      /* SMLAL<Q> <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>].
3034
   <Vm> Is the vector register (V0-V31) or (V0-V15), whose
3035
   number is encoded in "size:M:Rm":
3036
   size <Vm>
3037
   00   RESERVED
3038
   01   0:Rm
3039
   10   M:Rm
3040
   11   RESERVED  */
3041
100k
      if (type == AARCH64_OPND_Em16
3042
46.8k
    && (qualifier == AARCH64_OPND_QLF_S_H
3043
9.66k
        || qualifier == AARCH64_OPND_QLF_S_2B)
3044
40.0k
    && !value_in_range_p (opnd->reglane.regno, 0, 15))
3045
0
  {
3046
0
    set_regno_out_of_range_error (mismatch_detail, idx, 0, 15);
3047
0
    return false;
3048
0
  }
3049
100k
      if (type == AARCH64_OPND_Em8
3050
3.87k
    && !value_in_range_p (opnd->reglane.regno, 0, 7))
3051
0
  {
3052
0
    set_regno_out_of_range_error (mismatch_detail, idx, 0, 7);
3053
0
    return 0;
3054
0
  }
3055
100k
      break;
3056
3057
614k
    case AARCH64_OPND_CLASS_MODIFIED_REG:
3058
614k
      assert (idx == 1 || idx == 2);
3059
614k
      switch (type)
3060
614k
  {
3061
61.0k
  case AARCH64_OPND_Rm_EXT:
3062
61.0k
    if (!aarch64_extend_operator_p (opnd->shifter.kind)
3063
0
        && opnd->shifter.kind != AARCH64_MOD_LSL)
3064
0
      {
3065
0
        set_other_error (mismatch_detail, idx,
3066
0
             _("extend operator expected"));
3067
0
        return false;
3068
0
      }
3069
    /* It is not optional unless at least one of "Rd" or "Rn" is '11111'
3070
       (i.e. SP), in which case it defaults to LSL. The LSL alias is
3071
       only valid when "Rd" or "Rn" is '11111', and is preferred in that
3072
       case.  */
3073
61.0k
    if (!aarch64_stack_pointer_p (opnds + 0)
3074
59.6k
        && (idx != 2 || !aarch64_stack_pointer_p (opnds + 1)))
3075
57.7k
      {
3076
57.7k
        if (!opnd->shifter.operator_present)
3077
0
    {
3078
0
      set_other_error (mismatch_detail, idx,
3079
0
           _("missing extend operator"));
3080
0
      return false;
3081
0
    }
3082
57.7k
        else if (opnd->shifter.kind == AARCH64_MOD_LSL)
3083
0
    {
3084
0
      set_other_error (mismatch_detail, idx,
3085
0
           _("'LSL' operator not allowed"));
3086
0
      return false;
3087
0
    }
3088
57.7k
      }
3089
61.0k
    assert (opnd->shifter.operator_present  /* Default to LSL.  */
3090
61.0k
      || opnd->shifter.kind == AARCH64_MOD_LSL);
3091
61.0k
    if (!value_in_range_p (opnd->shifter.amount, 0, 4))
3092
8.62k
      {
3093
8.62k
        set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, 4);
3094
8.62k
        return false;
3095
8.62k
      }
3096
    /* In the 64-bit form, the final register operand is written as Wm
3097
       for all but the (possibly omitted) UXTX/LSL and SXTX
3098
       operators.
3099
       N.B. GAS allows X register to be used with any operator as a
3100
       programming convenience.  */
3101
52.4k
    if (qualifier == AARCH64_OPND_QLF_X
3102
4.41k
        && opnd->shifter.kind != AARCH64_MOD_LSL
3103
4.41k
        && opnd->shifter.kind != AARCH64_MOD_UXTX
3104
2.01k
        && opnd->shifter.kind != AARCH64_MOD_SXTX)
3105
0
      {
3106
0
        set_other_error (mismatch_detail, idx, _("W register expected"));
3107
0
        return false;
3108
0
      }
3109
52.4k
    break;
3110
3111
552k
  case AARCH64_OPND_Rm_SFT:
3112
    /* ROR is not available to the shifted register operand in
3113
       arithmetic instructions.  */
3114
552k
    if (!aarch64_shift_operator_p (opnd->shifter.kind))
3115
0
      {
3116
0
        set_other_error (mismatch_detail, idx,
3117
0
             _("shift operator expected"));
3118
0
        return false;
3119
0
      }
3120
552k
    if (opnd->shifter.kind == AARCH64_MOD_ROR
3121
87.4k
        && opcode->iclass != log_shift)
3122
0
      {
3123
0
        set_other_error (mismatch_detail, idx,
3124
0
             _("'ROR' operator not allowed"));
3125
0
        return false;
3126
0
      }
3127
552k
    num = qualifier == AARCH64_OPND_QLF_W ? 31 : 63;
3128
552k
    if (!value_in_range_p (opnd->shifter.amount, 0, num))
3129
69.9k
      {
3130
69.9k
        set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, num);
3131
69.9k
        return false;
3132
69.9k
      }
3133
482k
    break;
3134
3135
482k
  case AARCH64_OPND_Rm_LSL:
3136
    /* We expect here that opnd->shifter.kind != AARCH64_MOD_LSL
3137
       because the parser already restricts the type of shift to LSL only,
3138
       so another check of shift kind would be redundant.  */
3139
893
    if (!value_in_range_p (opnd->shifter.amount, 0, 7))
3140
0
      {
3141
0
        set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, 7);
3142
0
        return false;
3143
0
      }
3144
893
    break;
3145
3146
893
  default:
3147
0
    break;
3148
614k
  }
3149
535k
      break;
3150
3151
1.86M
    default:
3152
1.86M
      break;
3153
19.1M
    }
3154
3155
18.9M
  return true;
3156
19.1M
}
3157
3158
/* Main entrypoint for the operand constraint checking.
3159
3160
   Return 1 if operands of *INST meet the constraint applied by the operand
3161
   codes and operand qualifiers; otherwise return 0 and if MISMATCH_DETAIL is
3162
   not NULL, return the detail of the error in *MISMATCH_DETAIL.  N.B. when
3163
   adding more constraint checking, make sure MISMATCH_DETAIL->KIND is set
3164
   with a proper error kind rather than AARCH64_OPDE_NIL (GAS asserts non-NIL
3165
   error kind when it is notified that an instruction does not pass the check).
3166
3167
   Un-determined operand qualifiers may get established during the process.  */
3168
3169
bool
3170
aarch64_match_operands_constraint (aarch64_inst *inst,
3171
           aarch64_operand_error *mismatch_detail)
3172
8.24M
{
3173
8.24M
  int i;
3174
3175
8.24M
  DEBUG_TRACE ("enter");
3176
3177
8.24M
  i = inst->opcode->tied_operand;
3178
3179
8.24M
  if (i > 0)
3180
90.5k
    {
3181
      /* Check for tied_operands with specific opcode iclass.  */
3182
90.5k
      switch (inst->opcode->iclass)
3183
90.5k
        {
3184
        /* For SME LDR and STR instructions #imm must have the same numerical
3185
           value for both operands.
3186
        */
3187
956
        case sme_ldr:
3188
996
        case sme_str:
3189
996
          assert (inst->operands[0].type == AARCH64_OPND_SME_ZA_array_off4);
3190
996
          assert (inst->operands[1].type == AARCH64_OPND_SME_ADDR_RI_U4xVL);
3191
996
          if (inst->operands[0].indexed_za.index.imm
3192
996
              != inst->operands[1].addr.offset.imm)
3193
0
            {
3194
0
              if (mismatch_detail)
3195
0
                {
3196
0
                  mismatch_detail->kind = AARCH64_OPDE_UNTIED_IMMS;
3197
0
                  mismatch_detail->index = i;
3198
0
                }
3199
0
              return false;
3200
0
            }
3201
996
          break;
3202
3203
89.5k
        default:
3204
89.5k
    {
3205
      /* Check for cases where a source register needs to be the
3206
         same as the destination register.  Do this before
3207
         matching qualifiers since if an instruction has both
3208
         invalid tying and invalid qualifiers, the error about
3209
         qualifiers would suggest several alternative instructions
3210
         that also have invalid tying.  */
3211
89.5k
      enum aarch64_operand_class op_class
3212
89.5k
         = aarch64_get_operand_class (inst->operands[0].type);
3213
89.5k
      assert (aarch64_get_operand_class (inst->operands[i].type)
3214
89.5k
        == op_class);
3215
89.5k
      if (op_class == AARCH64_OPND_CLASS_SVE_REGLIST
3216
89.5k
    ? ((inst->operands[0].reglist.first_regno
3217
395
        != inst->operands[i].reglist.first_regno)
3218
395
       || (inst->operands[0].reglist.num_regs
3219
395
           != inst->operands[i].reglist.num_regs)
3220
395
       || (inst->operands[0].reglist.stride
3221
395
           != inst->operands[i].reglist.stride))
3222
89.5k
    : (inst->operands[0].reg.regno
3223
89.1k
       != inst->operands[i].reg.regno))
3224
0
        {
3225
0
    if (mismatch_detail)
3226
0
      {
3227
0
        mismatch_detail->kind = AARCH64_OPDE_UNTIED_OPERAND;
3228
0
        mismatch_detail->index = i;
3229
0
        mismatch_detail->error = NULL;
3230
0
      }
3231
0
    return false;
3232
0
        }
3233
89.5k
      break;
3234
89.5k
    }
3235
90.5k
        }
3236
90.5k
    }
3237
3238
  /* Match operands' qualifier.
3239
     *INST has already had qualifier establish for some, if not all, of
3240
     its operands; we need to find out whether these established
3241
     qualifiers match one of the qualifier sequence in
3242
     INST->OPCODE->QUALIFIERS_LIST.  If yes, we will assign each operand
3243
     with the corresponding qualifier in such a sequence.
3244
     Only basic operand constraint checking is done here; the more thorough
3245
     constraint checking will carried out by operand_general_constraint_met_p,
3246
     which has be to called after this in order to get all of the operands'
3247
     qualifiers established.  */
3248
8.24M
  int invalid_count;
3249
8.24M
  if (match_operands_qualifier (inst, true /* update_p */,
3250
8.24M
        &invalid_count) == 0)
3251
43.7k
    {
3252
43.7k
      DEBUG_TRACE ("FAIL on operand qualifier matching");
3253
43.7k
      if (mismatch_detail)
3254
0
  {
3255
    /* Return an error type to indicate that it is the qualifier
3256
       matching failure; we don't care about which operand as there
3257
       are enough information in the opcode table to reproduce it.  */
3258
0
    mismatch_detail->kind = AARCH64_OPDE_INVALID_VARIANT;
3259
0
    mismatch_detail->index = -1;
3260
0
    mismatch_detail->error = NULL;
3261
0
    mismatch_detail->data[0].i = invalid_count;
3262
0
  }
3263
43.7k
      return false;
3264
43.7k
    }
3265
3266
  /* Match operands' constraint.  */
3267
27.1M
  for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
3268
27.1M
    {
3269
27.1M
      enum aarch64_opnd type = inst->opcode->operands[i];
3270
27.1M
      if (type == AARCH64_OPND_NIL)
3271
8.00M
  break;
3272
19.1M
      if (inst->operands[i].skip)
3273
0
  {
3274
0
    DEBUG_TRACE ("skip the incomplete operand %d", i);
3275
0
    continue;
3276
0
  }
3277
19.1M
      if (!operand_general_constraint_met_p (inst->operands, i, type,
3278
19.1M
               inst->opcode, mismatch_detail))
3279
192k
  {
3280
192k
    DEBUG_TRACE ("FAIL on operand %d", i);
3281
192k
    return false;
3282
192k
  }
3283
19.1M
    }
3284
3285
  /* Check constraints involving multiple operands.  */
3286
8.00M
  if (inst->opcode->flags & F_REQUIRES_SP)
3287
5.62k
    {
3288
5.62k
      bool sp_found = false;
3289
16.1k
      for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
3290
16.1k
  {
3291
16.1k
    enum aarch64_opnd type = inst->opcode->operands[i];
3292
16.1k
    if (type == AARCH64_OPND_NIL)
3293
5.22k
      break;
3294
10.9k
    if (aarch64_stack_pointer_p (&(inst->operands[i])))
3295
401
      {
3296
401
        sp_found = true;
3297
401
        break;
3298
401
      }
3299
10.9k
  }
3300
5.62k
      if (!sp_found)
3301
5.22k
  {
3302
5.22k
    set_other_error (mismatch_detail, -1,
3303
5.22k
         _("expected at least one stack pointer operand"));
3304
5.22k
    return false;
3305
5.22k
  }
3306
5.62k
    }
3307
3308
7.99M
  DEBUG_TRACE ("PASS");
3309
3310
7.99M
  return true;
3311
8.00M
}
3312
3313
/* Replace INST->OPCODE with OPCODE and return the replaced OPCODE.
3314
   Also updates the TYPE of each INST->OPERANDS with the corresponding
3315
   value of OPCODE->OPERANDS.
3316
3317
   Note that some operand qualifiers may need to be manually cleared by
3318
   the caller before it further calls the aarch64_opcode_encode; by
3319
   doing this, it helps the qualifier matching facilities work
3320
   properly.  */
3321
3322
const aarch64_opcode*
3323
aarch64_replace_opcode (aarch64_inst *inst, const aarch64_opcode *opcode)
3324
104k
{
3325
104k
  int i;
3326
104k
  const aarch64_opcode *old = inst->opcode;
3327
3328
104k
  inst->opcode = opcode;
3329
3330
  /* Update the operand types.  */
3331
385k
  for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
3332
385k
    {
3333
385k
      inst->operands[i].type = opcode->operands[i];
3334
385k
      if (opcode->operands[i] == AARCH64_OPND_NIL)
3335
104k
  break;
3336
385k
    }
3337
3338
104k
  DEBUG_TRACE ("replace %s with %s", old->name, opcode->name);
3339
3340
104k
  return old;
3341
104k
}
3342
3343
int
3344
aarch64_operand_index (const enum aarch64_opnd *operands, enum aarch64_opnd operand)
3345
187k
{
3346
187k
  int i;
3347
219k
  for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
3348
219k
    if (operands[i] == operand)
3349
181k
      return i;
3350
37.6k
    else if (operands[i] == AARCH64_OPND_NIL)
3351
5.65k
      break;
3352
5.65k
  return -1;
3353
187k
}
3354

3355
/* R0...R30, followed by FOR31.  */
3356
#define BANK(R, FOR31) \
3357
  { R  (0), R  (1), R  (2), R  (3), R  (4), R  (5), R  (6), R  (7), \
3358
    R  (8), R  (9), R (10), R (11), R (12), R (13), R (14), R (15), \
3359
    R (16), R (17), R (18), R (19), R (20), R (21), R (22), R (23), \
3360
    R (24), R (25), R (26), R (27), R (28), R (29), R (30),  FOR31 }
3361
/* [0][0]  32-bit integer regs with sp   Wn
3362
   [0][1]  64-bit integer regs with sp   Xn  sf=1
3363
   [1][0]  32-bit integer regs with #0   Wn
3364
   [1][1]  64-bit integer regs with #0   Xn  sf=1 */
3365
static const char *int_reg[2][2][32] = {
3366
#define R32(X) "w" #X
3367
#define R64(X) "x" #X
3368
  { BANK (R32, "wsp"), BANK (R64, "sp") },
3369
  { BANK (R32, "wzr"), BANK (R64, "xzr") }
3370
#undef R64
3371
#undef R32
3372
};
3373
3374
/* Names of the SVE vector registers, first with .S suffixes,
3375
   then with .D suffixes.  */
3376
3377
static const char *sve_reg[2][32] = {
3378
#define ZS(X) "z" #X ".s"
3379
#define ZD(X) "z" #X ".d"
3380
  BANK (ZS, ZS (31)), BANK (ZD, ZD (31))
3381
#undef ZD
3382
#undef ZS
3383
};
3384
#undef BANK
3385
3386
/* Return the integer register name.
3387
   if SP_REG_P is not 0, R31 is an SP reg, other R31 is the zero reg.  */
3388
3389
static inline const char *
3390
get_int_reg_name (int regno, aarch64_opnd_qualifier_t qualifier, int sp_reg_p)
3391
4.92M
{
3392
4.92M
  const int has_zr = sp_reg_p ? 0 : 1;
3393
4.92M
  const int is_64 = aarch64_get_qualifier_esize (qualifier) == 4 ? 0 : 1;
3394
4.92M
  return int_reg[has_zr][is_64][regno];
3395
4.92M
}
3396
3397
/* Like get_int_reg_name, but IS_64 is always 1.  */
3398
3399
static inline const char *
3400
get_64bit_int_reg_name (int regno, int sp_reg_p)
3401
1.68M
{
3402
1.68M
  const int has_zr = sp_reg_p ? 0 : 1;
3403
1.68M
  return int_reg[has_zr][1][regno];
3404
1.68M
}
3405
3406
/* Get the name of the integer offset register in OPND, using the shift type
3407
   to decide whether it's a word or doubleword.  */
3408
3409
static inline const char *
3410
get_offset_int_reg_name (const aarch64_opnd_info *opnd)
3411
157k
{
3412
157k
  switch (opnd->shifter.kind)
3413
157k
    {
3414
2.07k
    case AARCH64_MOD_UXTW:
3415
4.91k
    case AARCH64_MOD_SXTW:
3416
4.91k
      return get_int_reg_name (opnd->addr.offset.regno, AARCH64_OPND_QLF_W, 0);
3417
3418
147k
    case AARCH64_MOD_LSL:
3419
152k
    case AARCH64_MOD_SXTX:
3420
152k
      return get_int_reg_name (opnd->addr.offset.regno, AARCH64_OPND_QLF_X, 0);
3421
3422
0
    default:
3423
0
      abort ();
3424
157k
    }
3425
157k
}
3426
3427
/* Get the name of the SVE vector offset register in OPND, using the operand
3428
   qualifier to decide whether the suffix should be .S or .D.  */
3429
3430
static inline const char *
3431
get_addr_sve_reg_name (int regno, aarch64_opnd_qualifier_t qualifier)
3432
143k
{
3433
143k
  assert (qualifier == AARCH64_OPND_QLF_S_S
3434
143k
    || qualifier == AARCH64_OPND_QLF_S_D);
3435
143k
  return sve_reg[qualifier == AARCH64_OPND_QLF_S_D][regno];
3436
143k
}
3437
3438
/* Types for expanding an encoded 8-bit value to a floating-point value.  */
3439
3440
typedef union
3441
{
3442
  uint64_t i;
3443
  double   d;
3444
} double_conv_t;
3445
3446
typedef union
3447
{
3448
  uint32_t i;
3449
  float    f;
3450
} single_conv_t;
3451
3452
typedef union
3453
{
3454
  uint32_t i;
3455
  float    f;
3456
} half_conv_t;
3457
3458
/* IMM8 is an 8-bit floating-point constant with sign, 3-bit exponent and
3459
   normalized 4 bits of precision, encoded in "a:b:c:d:e:f:g:h" or FLD_imm8
3460
   (depending on the type of the instruction).  IMM8 will be expanded to a
3461
   single-precision floating-point value (SIZE == 4) or a double-precision
3462
   floating-point value (SIZE == 8).  A half-precision floating-point value
3463
   (SIZE == 2) is expanded to a single-precision floating-point value.  The
3464
   expanded value is returned.  */
3465
3466
static uint64_t
3467
expand_fp_imm (int size, uint32_t imm8)
3468
3.49k
{
3469
3.49k
  uint64_t imm = 0;
3470
3.49k
  uint32_t imm8_7, imm8_6_0, imm8_6, imm8_6_repl4;
3471
3472
3.49k
  imm8_7 = (imm8 >> 7) & 0x01;  /* imm8<7>   */
3473
3.49k
  imm8_6_0 = imm8 & 0x7f; /* imm8<6:0> */
3474
3.49k
  imm8_6 = imm8_6_0 >> 6; /* imm8<6>   */
3475
3.49k
  imm8_6_repl4 = (imm8_6 << 3) | (imm8_6 << 2)
3476
3.49k
    | (imm8_6 << 1) | imm8_6; /* Replicate(imm8<6>,4) */
3477
3.49k
  if (size == 8)
3478
754
    {
3479
754
      imm = (imm8_7 << (63-32))   /* imm8<7>  */
3480
754
  | ((imm8_6 ^ 1) << (62-32)) /* NOT(imm8<6)  */
3481
754
  | (imm8_6_repl4 << (58-32)) | (imm8_6 << (57-32))
3482
754
  | (imm8_6 << (56-32)) | (imm8_6 << (55-32)) /* Replicate(imm8<6>,7) */
3483
754
  | (imm8_6_0 << (48-32));  /* imm8<6>:imm8<5:0>    */
3484
754
      imm <<= 32;
3485
754
    }
3486
2.74k
  else if (size == 4 || size == 2)
3487
2.74k
    {
3488
2.74k
      imm = (imm8_7 << 31)  /* imm8<7>              */
3489
2.74k
  | ((imm8_6 ^ 1) << 30)  /* NOT(imm8<6>)         */
3490
2.74k
  | (imm8_6_repl4 << 26)  /* Replicate(imm8<6>,4) */
3491
2.74k
  | (imm8_6_0 << 19); /* imm8<6>:imm8<5:0>    */
3492
2.74k
    }
3493
0
  else
3494
0
    {
3495
      /* An unsupported size.  */
3496
0
      assert (0);
3497
0
    }
3498
3499
3.49k
  return imm;
3500
3.49k
}
3501
3502
/* Return a string based on FMT with the register style applied.  */
3503
3504
static const char *
3505
style_reg (struct aarch64_styler *styler, const char *fmt, ...)
3506
12.1M
{
3507
12.1M
  const char *txt;
3508
12.1M
  va_list ap;
3509
3510
12.1M
  va_start (ap, fmt);
3511
12.1M
  txt = styler->apply_style (styler, dis_style_register, fmt, ap);
3512
12.1M
  va_end (ap);
3513
3514
12.1M
  return txt;
3515
12.1M
}
3516
3517
/* Return a string based on FMT with the immediate style applied.  */
3518
3519
static const char *
3520
style_imm (struct aarch64_styler *styler, const char *fmt, ...)
3521
4.90M
{
3522
4.90M
  const char *txt;
3523
4.90M
  va_list ap;
3524
3525
4.90M
  va_start (ap, fmt);
3526
4.90M
  txt = styler->apply_style (styler, dis_style_immediate, fmt, ap);
3527
4.90M
  va_end (ap);
3528
3529
4.90M
  return txt;
3530
4.90M
}
3531
3532
/* Return a string based on FMT with the sub-mnemonic style applied.  */
3533
3534
static const char *
3535
style_sub_mnem (struct aarch64_styler *styler, const char *fmt, ...)
3536
803k
{
3537
803k
  const char *txt;
3538
803k
  va_list ap;
3539
3540
803k
  va_start (ap, fmt);
3541
803k
  txt = styler->apply_style (styler, dis_style_sub_mnemonic, fmt, ap);
3542
803k
  va_end (ap);
3543
3544
803k
  return txt;
3545
803k
}
3546
3547
/* Return a string based on FMT with the address style applied.  */
3548
3549
static const char *
3550
style_addr (struct aarch64_styler *styler, const char *fmt, ...)
3551
1.47M
{
3552
1.47M
  const char *txt;
3553
1.47M
  va_list ap;
3554
3555
1.47M
  va_start (ap, fmt);
3556
1.47M
  txt = styler->apply_style (styler, dis_style_address, fmt, ap);
3557
1.47M
  va_end (ap);
3558
3559
1.47M
  return txt;
3560
1.47M
}
3561
3562
/* Produce the string representation of the register list operand *OPND
3563
   in the buffer pointed by BUF of size SIZE.  PREFIX is the part of
3564
   the register name that comes before the register number, such as "v".  */
3565
static void
3566
print_register_list (char *buf, size_t size, const aarch64_opnd_info *opnd,
3567
         const char *prefix, struct aarch64_styler *styler)
3568
419k
{
3569
419k
  const int mask = (prefix[0] == 'p' ? 15 : 31);
3570
419k
  const int num_regs = opnd->reglist.num_regs;
3571
419k
  const int stride = opnd->reglist.stride;
3572
419k
  const int first_reg = opnd->reglist.first_regno;
3573
419k
  const int last_reg = (first_reg + (num_regs - 1) * stride) & mask;
3574
419k
  const char *qlf_name = aarch64_get_qualifier_name (opnd->qualifier);
3575
419k
  char tb[16];  /* Temporary buffer.  */
3576
3577
419k
  assert (opnd->type != AARCH64_OPND_LEt || opnd->reglist.has_index);
3578
419k
  assert (num_regs >= 1 && num_regs <= 4);
3579
3580
  /* Prepare the index if any.  */
3581
419k
  if (opnd->reglist.has_index)
3582
    /* PR 21096: The %100 is to silence a warning about possible truncation.  */
3583
21.1k
    snprintf (tb, sizeof (tb), "[%s]",
3584
21.1k
        style_imm (styler, "%" PRIi64, (opnd->reglist.index % 100)));
3585
397k
  else
3586
397k
    tb[0] = '\0';
3587
3588
  /* The hyphenated form is preferred for disassembly if there is
3589
     more than one register in the list, and the register numbers
3590
     are monotonically increasing in increments of one.  */
3591
419k
  if (stride == 1 && num_regs > 1)
3592
128k
    if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
3593
509
      snprintf (buf, size, "{%s-%s}%s",
3594
509
    style_reg (styler, "%s%d", prefix, first_reg),
3595
509
    style_reg (styler, "%s%d", prefix, last_reg), tb);
3596
127k
    else
3597
127k
      snprintf (buf, size, "{%s-%s}%s",
3598
127k
    style_reg (styler, "%s%d.%s", prefix, first_reg, qlf_name),
3599
127k
    style_reg (styler, "%s%d.%s", prefix, last_reg, qlf_name), tb);
3600
291k
  else
3601
291k
    {
3602
291k
      const int reg0 = first_reg;
3603
291k
      const int reg1 = (first_reg + stride) & mask;
3604
291k
      const int reg2 = (first_reg + stride * 2) & mask;
3605
291k
      const int reg3 = (first_reg + stride * 3) & mask;
3606
3607
291k
      switch (num_regs)
3608
291k
  {
3609
277k
  case 1:
3610
277k
    snprintf (buf, size, "{%s}%s",
3611
277k
        style_reg (styler, "%s%d.%s", prefix, reg0, qlf_name),
3612
277k
        tb);
3613
277k
    break;
3614
8.96k
  case 2:
3615
8.96k
    snprintf (buf, size, "{%s, %s}%s",
3616
8.96k
        style_reg (styler, "%s%d.%s", prefix, reg0, qlf_name),
3617
8.96k
        style_reg (styler, "%s%d.%s", prefix, reg1, qlf_name),
3618
8.96k
        tb);
3619
8.96k
    break;
3620
0
  case 3:
3621
0
    snprintf (buf, size, "{%s, %s, %s}%s",
3622
0
        style_reg (styler, "%s%d.%s", prefix, reg0, qlf_name),
3623
0
        style_reg (styler, "%s%d.%s", prefix, reg1, qlf_name),
3624
0
        style_reg (styler, "%s%d.%s", prefix, reg2, qlf_name),
3625
0
        tb);
3626
0
    break;
3627
4.39k
  case 4:
3628
4.39k
    snprintf (buf, size, "{%s, %s, %s, %s}%s",
3629
4.39k
        style_reg (styler, "%s%d.%s", prefix, reg0, qlf_name),
3630
4.39k
        style_reg (styler, "%s%d.%s", prefix, reg1, qlf_name),
3631
4.39k
        style_reg (styler, "%s%d.%s", prefix, reg2, qlf_name),
3632
4.39k
        style_reg (styler, "%s%d.%s", prefix, reg3, qlf_name),
3633
4.39k
        tb);
3634
4.39k
    break;
3635
291k
  }
3636
291k
    }
3637
419k
}
3638
3639
/* Print the register+immediate address in OPND to BUF, which has SIZE
3640
   characters.  BASE is the name of the base register.  */
3641
3642
static void
3643
print_immediate_offset_address (char *buf, size_t size,
3644
        const aarch64_opnd_info *opnd,
3645
        const char *base,
3646
        struct aarch64_styler *styler)
3647
905k
{
3648
905k
  if (opnd->addr.writeback)
3649
315k
    {
3650
315k
      if (opnd->addr.preind)
3651
161k
        {
3652
161k
    if (opnd->type == AARCH64_OPND_ADDR_SIMM10 && !opnd->addr.offset.imm)
3653
105
      snprintf (buf, size, "[%s]!", style_reg (styler, base));
3654
161k
          else
3655
161k
      snprintf (buf, size, "[%s, %s]!",
3656
161k
          style_reg (styler, base),
3657
161k
          style_imm (styler, "#%d", opnd->addr.offset.imm));
3658
161k
        }
3659
153k
      else
3660
153k
  snprintf (buf, size, "[%s], %s",
3661
153k
      style_reg (styler, base),
3662
153k
      style_imm (styler, "#%d", opnd->addr.offset.imm));
3663
315k
    }
3664
589k
  else
3665
589k
    {
3666
589k
      if (opnd->shifter.operator_present)
3667
88.0k
  {
3668
88.0k
    assert (opnd->shifter.kind == AARCH64_MOD_MUL_VL);
3669
88.0k
    snprintf (buf, size, "[%s, %s, %s]",
3670
88.0k
        style_reg (styler, base),
3671
88.0k
        style_imm (styler, "#%d", opnd->addr.offset.imm),
3672
88.0k
        style_sub_mnem (styler, "mul vl"));
3673
88.0k
  }
3674
501k
      else if (opnd->addr.offset.imm)
3675
408k
  snprintf (buf, size, "[%s, %s]",
3676
408k
      style_reg (styler, base),
3677
408k
      style_imm (styler, "#%d", opnd->addr.offset.imm));
3678
93.6k
      else
3679
93.6k
  snprintf (buf, size, "[%s]", style_reg (styler, base));
3680
589k
    }
3681
905k
}
3682
3683
/* Produce the string representation of the register offset address operand
3684
   *OPND in the buffer pointed by BUF of size SIZE.  BASE and OFFSET are
3685
   the names of the base and offset registers.  */
3686
static void
3687
print_register_offset_address (char *buf, size_t size,
3688
             const aarch64_opnd_info *opnd,
3689
             const char *base, const char *offset,
3690
             struct aarch64_styler *styler)
3691
281k
{
3692
281k
  char tb[32];      /* Temporary buffer.  */
3693
281k
  bool print_extend_p = true;
3694
281k
  bool print_amount_p = true;
3695
281k
  const char *shift_name = aarch64_operand_modifiers[opnd->shifter.kind].name;
3696
3697
  /* This is the case where offset is the optional argument and the optional
3698
     argument is ignored in the disassembly.  */
3699
281k
  if (opnd->type == AARCH64_OPND_SVE_ADDR_ZX && offset != NULL
3700
16.0k
      && strcmp (offset,"xzr") == 0)
3701
312
    {
3702
      /* Example: [<Zn>.S{, <Xm>}].
3703
   When the assembly is [Z0.S, XZR] or [Z0.S], Xm is XZR in both the cases
3704
   and the preferred disassembly is [Z0.S], ignoring the optional Xm.  */
3705
312
      snprintf (buf, size, "[%s]", style_reg (styler, base));
3706
312
    }
3707
281k
  else
3708
281k
    {
3709
281k
      if (!opnd->shifter.amount && (opnd->qualifier != AARCH64_OPND_QLF_S_B
3710
5.37k
            || !opnd->shifter.amount_present))
3711
135k
  {
3712
    /* Not print the shift/extend amount when the amount is zero and
3713
       when it is not the special case of 8-bit load/store
3714
       instruction.  */
3715
135k
   print_amount_p = false;
3716
   /* Likewise, no need to print the shift operator LSL in such a
3717
      situation.  */
3718
135k
   if (opnd->shifter.kind == AARCH64_MOD_LSL)
3719
84.5k
     print_extend_p = false;
3720
135k
  }
3721
3722
      /* Prepare for the extend/shift.  */
3723
281k
      if (print_extend_p)
3724
197k
  {
3725
197k
    if (print_amount_p)
3726
145k
      snprintf (tb, sizeof (tb), ", %s %s",
3727
145k
          style_sub_mnem (styler, shift_name),
3728
145k
          style_imm (styler, "#%" PRIi64,
3729
    /* PR 21096: The %100 is to silence a warning about possible
3730
       truncation.  */
3731
145k
         (opnd->shifter.amount % 100)));
3732
51.3k
    else
3733
51.3k
      snprintf (tb, sizeof (tb), ", %s",
3734
51.3k
          style_sub_mnem (styler, shift_name));
3735
197k
  }
3736
84.5k
      else
3737
84.5k
  tb[0] = '\0';
3738
3739
281k
      snprintf (buf, size, "[%s, %s%s]", style_reg (styler, base),
3740
281k
    style_reg (styler, offset), tb);
3741
281k
    }
3742
281k
}
3743
3744
/* Print ZA tiles from imm8 in ZERO instruction.
3745
3746
   The preferred disassembly of this instruction uses the shortest list of tile
3747
   names that represent the encoded immediate mask.
3748
3749
   For example:
3750
    * An all-ones immediate is disassembled as {ZA}.
3751
    * An all-zeros immediate is disassembled as an empty list { }.
3752
*/
3753
static void
3754
print_sme_za_list (char *buf, size_t size, int mask,
3755
       struct aarch64_styler *styler)
3756
292
{
3757
292
  static const struct {
3758
292
    unsigned char mask;
3759
292
    char name[7];
3760
292
  } zan[] = {
3761
292
    { 0xff, "za" },
3762
292
    { 0x55, "za0.h" },
3763
292
    { 0xaa, "za1.h" },
3764
292
    { 0x11, "za0.s" },
3765
292
    { 0x22, "za1.s" },
3766
292
    { 0x44, "za2.s" },
3767
292
    { 0x88, "za3.s" },
3768
292
    { 0x01, "za0.d" },
3769
292
    { 0x02, "za1.d" },
3770
292
    { 0x04, "za2.d" },
3771
292
    { 0x08, "za3.d" },
3772
292
    { 0x10, "za4.d" },
3773
292
    { 0x20, "za5.d" },
3774
292
    { 0x40, "za6.d" },
3775
292
    { 0x80, "za7.d" },
3776
292
    { 0x00, " " },
3777
292
  };
3778
292
  int k;
3779
3780
292
  k = snprintf (buf, size, "{");
3781
2.53k
  for (unsigned int i = 0; i < ARRAY_SIZE (zan); i++)
3782
2.53k
    {
3783
2.53k
      if ((mask & zan[i].mask) == zan[i].mask)
3784
832
  {
3785
832
    mask &= ~zan[i].mask;
3786
832
    if (k > 1)
3787
551
      k += snprintf (buf + k, size - k, ", ");
3788
3789
832
    k += snprintf (buf + k, size - k, "%s",
3790
832
       style_reg (styler, zan[i].name));
3791
832
  }
3792
2.53k
      if (mask == 0)
3793
292
        break;
3794
2.53k
    }
3795
292
  snprintf (buf + k, size - k, "}");
3796
292
}
3797
3798
/* Generate the string representation of the operand OPNDS[IDX] for OPCODE
3799
   in *BUF.  The caller should pass in the maximum size of *BUF in SIZE.
3800
   PC, PCREL_P and ADDRESS are used to pass in and return information about
3801
   the PC-relative address calculation, where the PC value is passed in
3802
   PC.  If the operand is pc-relative related, *PCREL_P (if PCREL_P non-NULL)
3803
   will return 1 and *ADDRESS (if ADDRESS non-NULL) will return the
3804
   calculated address; otherwise, *PCREL_P (if PCREL_P non-NULL) returns 0.
3805
3806
   The function serves both the disassembler and the assembler diagnostics
3807
   issuer, which is the reason why it lives in this file.  */
3808
3809
void
3810
aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
3811
           const aarch64_opcode *opcode,
3812
           const aarch64_opnd_info *opnds, int idx, int *pcrel_p,
3813
           bfd_vma *address, char** notes,
3814
           char *comment, size_t comment_size,
3815
           aarch64_feature_set features,
3816
           struct aarch64_styler *styler)
3817
15.9M
{
3818
15.9M
  unsigned int i, num_conds;
3819
15.9M
  const char *name = NULL;
3820
15.9M
  const aarch64_opnd_info *opnd = opnds + idx;
3821
15.9M
  enum aarch64_modifier_kind kind;
3822
15.9M
  uint64_t addr, enum_value;
3823
3824
15.9M
  if (comment != NULL)
3825
15.9M
    {
3826
15.9M
      assert (comment_size > 0);
3827
15.9M
      comment[0] = '\0';
3828
15.9M
    }
3829
0
  else
3830
15.9M
    assert (comment_size == 0);
3831
3832
15.9M
  buf[0] = '\0';
3833
15.9M
  if (pcrel_p)
3834
15.9M
    *pcrel_p = 0;
3835
3836
15.9M
  switch (opnd->type)
3837
15.9M
    {
3838
1.24M
    case AARCH64_OPND_Rd:
3839
1.88M
    case AARCH64_OPND_Rn:
3840
2.01M
    case AARCH64_OPND_Rm:
3841
3.32M
    case AARCH64_OPND_Rt:
3842
3.62M
    case AARCH64_OPND_Rt2:
3843
3.79M
    case AARCH64_OPND_Rs:
3844
3.82M
    case AARCH64_OPND_Ra:
3845
3.82M
    case AARCH64_OPND_Rt_IN_SYS_ALIASES:
3846
3.83M
    case AARCH64_OPND_Rt_LS64:
3847
3.83M
    case AARCH64_OPND_Rt_SYS:
3848
3.83M
    case AARCH64_OPND_PAIRREG:
3849
3.83M
    case AARCH64_OPND_PAIRREG_OR_XZR:
3850
3.83M
    case AARCH64_OPND_SVE_Rm:
3851
3.83M
    case AARCH64_OPND_LSE128_Rt:
3852
3.83M
    case AARCH64_OPND_LSE128_Rt2:
3853
      /* The optional-ness of <Xt> in e.g. IC <ic_op>{, <Xt>} is determined by
3854
   the <ic_op>, therefore we use opnd->present to override the
3855
   generic optional-ness information.  */
3856
3.83M
      if (opnd->type == AARCH64_OPND_Rt_SYS)
3857
387
  {
3858
387
    if (!opnd->present)
3859
15
      break;
3860
387
  }
3861
3.83M
      else if ((opnd->type == AARCH64_OPND_Rt_IN_SYS_ALIASES)
3862
77
         && (opnd->reg.regno
3863
77
       != get_optional_operand_default_value (opcode)))
3864
77
  {
3865
    /* Avoid printing an invalid additional value for Rt in SYS aliases such as
3866
       BRB, provide a helpful comment instead */
3867
77
    snprintf (comment, comment_size, "unpredictable encoding (Rt!=31): #%u", opnd->reg.regno);
3868
77
    break;
3869
77
  }
3870
      /* Omit the operand, e.g. RET.  */
3871
3.83M
      else if (optional_operand_p (opcode, idx)
3872
6.40k
         && (opnd->reg.regno
3873
6.40k
       == get_optional_operand_default_value (opcode)))
3874
2.49k
  break;
3875
3.83M
      assert (opnd->qualifier == AARCH64_OPND_QLF_W
3876
3.83M
        || opnd->qualifier == AARCH64_OPND_QLF_X);
3877
3.83M
      snprintf (buf, size, "%s",
3878
3.83M
    style_reg (styler, get_int_reg_name (opnd->reg.regno,
3879
3.83M
                 opnd->qualifier, 0)));
3880
3.83M
      break;
3881
3882
249k
    case AARCH64_OPND_Rd_SP:
3883
522k
    case AARCH64_OPND_Rn_SP:
3884
531k
    case AARCH64_OPND_Rt_SP:
3885
532k
    case AARCH64_OPND_SVE_Rn_SP:
3886
532k
    case AARCH64_OPND_Rm_SP:
3887
532k
      assert (opnd->qualifier == AARCH64_OPND_QLF_W
3888
532k
        || opnd->qualifier == AARCH64_OPND_QLF_X);
3889
532k
      snprintf (buf, size, "%s",
3890
532k
    style_reg (styler, get_int_reg_name (opnd->reg.regno,
3891
532k
                 opnd->qualifier, 1)));
3892
532k
      break;
3893
3894
30.2k
    case AARCH64_OPND_Rm_EXT:
3895
30.2k
      kind = opnd->shifter.kind;
3896
30.2k
      assert (idx == 1 || idx == 2);
3897
30.2k
      if ((aarch64_stack_pointer_p (opnds)
3898
29.2k
     || (idx == 2 && aarch64_stack_pointer_p (opnds + 1)))
3899
1.91k
    && ((opnd->qualifier == AARCH64_OPND_QLF_W
3900
827
         && opnds[0].qualifier == AARCH64_OPND_QLF_W
3901
478
         && kind == AARCH64_MOD_UXTW)
3902
1.82k
        || (opnd->qualifier == AARCH64_OPND_QLF_X
3903
1.09k
      && kind == AARCH64_MOD_UXTX)))
3904
1.01k
  {
3905
    /* 'LSL' is the preferred form in this case.  */
3906
1.01k
    kind = AARCH64_MOD_LSL;
3907
1.01k
    if (opnd->shifter.amount == 0)
3908
455
      {
3909
        /* Shifter omitted.  */
3910
455
        snprintf (buf, size, "%s",
3911
455
      style_reg (styler,
3912
455
           get_int_reg_name (opnd->reg.regno,
3913
455
                 opnd->qualifier, 0)));
3914
455
        break;
3915
455
      }
3916
1.01k
  }
3917
29.7k
      if (opnd->shifter.amount)
3918
23.3k
  snprintf (buf, size, "%s, %s %s",
3919
23.3k
      style_reg (styler, get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0)),
3920
23.3k
      style_sub_mnem (styler, aarch64_operand_modifiers[kind].name),
3921
23.3k
      style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
3922
6.39k
      else
3923
6.39k
  snprintf (buf, size, "%s, %s",
3924
6.39k
      style_reg (styler, get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0)),
3925
6.39k
      style_sub_mnem (styler, aarch64_operand_modifiers[kind].name));
3926
29.7k
      break;
3927
3928
340k
    case AARCH64_OPND_Rm_SFT:
3929
340k
      assert (opnd->qualifier == AARCH64_OPND_QLF_W
3930
340k
        || opnd->qualifier == AARCH64_OPND_QLF_X);
3931
340k
      if (opnd->shifter.amount == 0 && opnd->shifter.kind == AARCH64_MOD_LSL)
3932
38.0k
  snprintf (buf, size, "%s",
3933
38.0k
      style_reg (styler, get_int_reg_name (opnd->reg.regno,
3934
38.0k
                   opnd->qualifier, 0)));
3935
302k
      else
3936
302k
  snprintf (buf, size, "%s, %s %s",
3937
302k
      style_reg (styler, get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0)),
3938
302k
      style_sub_mnem (styler, aarch64_operand_modifiers[opnd->shifter.kind].name),
3939
302k
      style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
3940
340k
      break;
3941
3942
893
    case AARCH64_OPND_Rm_LSL:
3943
893
      assert (opnd->qualifier == AARCH64_OPND_QLF_X);
3944
893
      assert (opnd->shifter.kind == AARCH64_MOD_LSL);
3945
893
      if (opnd->shifter.amount == 0)
3946
252
  snprintf (buf, size, "%s",
3947
252
      style_reg (styler, get_int_reg_name (opnd->reg.regno,
3948
252
                   opnd->qualifier, 0)));
3949
641
      else
3950
641
  snprintf (buf, size, "%s, %s %s",
3951
641
      style_reg (styler, get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0)),
3952
641
      style_sub_mnem (styler, aarch64_operand_modifiers[opnd->shifter.kind].name),
3953
641
      style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
3954
893
      break;
3955
3956
121k
    case AARCH64_OPND_Fd:
3957
167k
    case AARCH64_OPND_Fn:
3958
222k
    case AARCH64_OPND_Fm:
3959
317k
    case AARCH64_OPND_Fa:
3960
807k
    case AARCH64_OPND_Ft:
3961
1.04M
    case AARCH64_OPND_Ft2:
3962
1.06M
    case AARCH64_OPND_Sd:
3963
1.09M
    case AARCH64_OPND_Sn:
3964
1.10M
    case AARCH64_OPND_Sm:
3965
1.10M
    case AARCH64_OPND_SVE_VZn:
3966
1.10M
    case AARCH64_OPND_SVE_Vd:
3967
1.10M
    case AARCH64_OPND_SVE_Vm:
3968
1.10M
    case AARCH64_OPND_SVE_Vn:
3969
1.10M
      snprintf (buf, size, "%s",
3970
1.10M
    style_reg (styler, "%s%d",
3971
1.10M
         aarch64_get_qualifier_name (opnd->qualifier),
3972
1.10M
         opnd->reg.regno));
3973
1.10M
      break;
3974
3975
10.2k
    case AARCH64_OPND_Va:
3976
307k
    case AARCH64_OPND_Vd:
3977
563k
    case AARCH64_OPND_Vn:
3978
739k
    case AARCH64_OPND_Vm:
3979
739k
      snprintf (buf, size, "%s",
3980
739k
    style_reg (styler, "v%d.%s", opnd->reg.regno,
3981
739k
         aarch64_get_qualifier_name (opnd->qualifier)));
3982
739k
      break;
3983
3984
2.04k
    case AARCH64_OPND_Ed:
3985
8.15k
    case AARCH64_OPND_En:
3986
44.1k
    case AARCH64_OPND_Em:
3987
91.0k
    case AARCH64_OPND_Em16:
3988
94.8k
    case AARCH64_OPND_Em8:
3989
94.8k
      snprintf (buf, size, "%s[%s]",
3990
94.8k
    style_reg (styler, "v%d.%s", opnd->reglane.regno,
3991
94.8k
         aarch64_get_qualifier_name (opnd->qualifier)),
3992
94.8k
    style_imm (styler, "%" PRIi64, opnd->reglane.index));
3993
94.8k
      break;
3994
3995
1.29k
    case AARCH64_OPND_Em_INDEX1_14:
3996
3.57k
    case AARCH64_OPND_Em_INDEX2_13:
3997
4.76k
    case AARCH64_OPND_Em_INDEX3_12:
3998
4.76k
      snprintf (buf, size, "%s[%s]",
3999
4.76k
    style_reg (styler, "v%d", opnd->reglane.regno),
4000
4.76k
    style_imm (styler, "%" PRIi64, opnd->reglane.index));
4001
4.76k
      break;
4002
4003
263
    case AARCH64_OPND_VdD1:
4004
1.22k
    case AARCH64_OPND_VnD1:
4005
1.22k
      snprintf (buf, size, "%s[%s]",
4006
1.22k
    style_reg (styler, "v%d.d", opnd->reg.regno),
4007
1.22k
    style_imm (styler, "1"));
4008
1.22k
      break;
4009
4010
17.0k
    case AARCH64_OPND_LVn:
4011
21.8k
    case AARCH64_OPND_LVn_LUT:
4012
36.2k
    case AARCH64_OPND_LVt:
4013
38.2k
    case AARCH64_OPND_LVt_AL:
4014
59.0k
    case AARCH64_OPND_LEt:
4015
59.0k
      print_register_list (buf, size, opnd, "v", styler);
4016
59.0k
      break;
4017
4018
97.6k
    case AARCH64_OPND_SVE_Pd:
4019
793k
    case AARCH64_OPND_SVE_Pg3:
4020
794k
    case AARCH64_OPND_SVE_Pg4_5:
4021
814k
    case AARCH64_OPND_SVE_Pg4_10:
4022
823k
    case AARCH64_OPND_SVE_Pg4_16:
4023
831k
    case AARCH64_OPND_SVE_Pm:
4024
839k
    case AARCH64_OPND_SVE_Pn:
4025
841k
    case AARCH64_OPND_SVE_Pt:
4026
920k
    case AARCH64_OPND_SME_Pm:
4027
920k
      if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
4028
154k
  snprintf (buf, size, "%s",
4029
154k
      style_reg (styler, "p%d", opnd->reg.regno));
4030
766k
      else if (opnd->qualifier == AARCH64_OPND_QLF_P_Z
4031
450k
         || opnd->qualifier == AARCH64_OPND_QLF_P_M)
4032
657k
  snprintf (buf, size, "%s",
4033
657k
      style_reg (styler, "p%d/%s", opnd->reg.regno,
4034
657k
           aarch64_get_qualifier_name (opnd->qualifier)));
4035
109k
      else
4036
109k
  snprintf (buf, size, "%s",
4037
109k
      style_reg (styler, "p%d.%s", opnd->reg.regno,
4038
109k
           aarch64_get_qualifier_name (opnd->qualifier)));
4039
920k
      break;
4040
4041
0
    case AARCH64_OPND_SVE_PNd:
4042
0
    case AARCH64_OPND_SVE_PNg4_10:
4043
0
    case AARCH64_OPND_SVE_PNn:
4044
0
    case AARCH64_OPND_SVE_PNt:
4045
2.73k
    case AARCH64_OPND_SME_PNd3:
4046
34.8k
    case AARCH64_OPND_SME_PNg3:
4047
34.8k
    case AARCH64_OPND_SME_PNn:
4048
34.8k
      if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
4049
10.4k
  snprintf (buf, size, "%s",
4050
10.4k
      style_reg (styler, "pn%d", opnd->reg.regno));
4051
24.4k
      else if (opnd->qualifier == AARCH64_OPND_QLF_P_Z
4052
2.78k
         || opnd->qualifier == AARCH64_OPND_QLF_P_M)
4053
21.6k
  snprintf (buf, size, "%s",
4054
21.6k
      style_reg (styler, "pn%d/%s", opnd->reg.regno,
4055
21.6k
           aarch64_get_qualifier_name (opnd->qualifier)));
4056
2.78k
      else
4057
2.78k
  snprintf (buf, size, "%s",
4058
2.78k
      style_reg (styler, "pn%d.%s", opnd->reg.regno,
4059
2.78k
           aarch64_get_qualifier_name (opnd->qualifier)));
4060
34.8k
      break;
4061
4062
903
    case AARCH64_OPND_SME_Pdx2:
4063
1.03k
    case AARCH64_OPND_SME_PdxN:
4064
1.03k
      print_register_list (buf, size, opnd, "p", styler);
4065
1.03k
      break;
4066
4067
132
    case AARCH64_OPND_SME_PNn3_INDEX1:
4068
182
    case AARCH64_OPND_SME_PNn3_INDEX2:
4069
182
      snprintf (buf, size, "%s[%s]",
4070
182
    style_reg (styler, "pn%d", opnd->reglane.regno),
4071
182
    style_imm (styler, "%" PRIi64, opnd->reglane.index));
4072
182
      break;
4073
4074
7.45k
    case AARCH64_OPND_SVE_Za_5:
4075
17.1k
    case AARCH64_OPND_SVE_Za_16:
4076
467k
    case AARCH64_OPND_SVE_Zd:
4077
512k
    case AARCH64_OPND_SVE_Zm_5:
4078
833k
    case AARCH64_OPND_SVE_Zm_16:
4079
1.33M
    case AARCH64_OPND_SVE_Zn:
4080
1.34M
    case AARCH64_OPND_SVE_Zt:
4081
1.34M
    case AARCH64_OPND_SME_Zm:
4082
1.34M
    case AARCH64_OPND_SME_Zm_17:
4083
1.35M
    case AARCH64_OPND_SME_Zn_6_3:
4084
1.36M
    case AARCH64_OPND_SME_Zm_17_3:
4085
1.36M
      if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
4086
2.85k
       snprintf (buf, size, "%s", style_reg (styler, "z%d", opnd->reg.regno));
4087
1.36M
      else
4088
1.36M
       snprintf (buf, size, "%s",
4089
1.36M
     style_reg (styler, "z%d.%s", opnd->reg.regno,
4090
1.36M
          aarch64_get_qualifier_name (opnd->qualifier)));
4091
1.36M
      break;
4092
4093
12.7k
    case AARCH64_OPND_SVE_ZnxN:
4094
289k
    case AARCH64_OPND_SVE_ZtxN:
4095
309k
    case AARCH64_OPND_SME_Zdnx2:
4096
317k
    case AARCH64_OPND_SME_Zdnx4:
4097
317k
    case AARCH64_OPND_SME_Znx2_6_3:
4098
318k
    case AARCH64_OPND_SME_Zmx2_17_3:
4099
321k
    case AARCH64_OPND_SME_Zmx2:
4100
321k
    case AARCH64_OPND_SME_Zmx4:
4101
321k
    case AARCH64_OPND_SME_Zmx2_INDEX_22:
4102
339k
    case AARCH64_OPND_SME_Znx2:
4103
339k
    case AARCH64_OPND_SME_Znx2_BIT_INDEX:
4104
345k
    case AARCH64_OPND_SME_Znx4:
4105
345k
    case AARCH64_OPND_SME_Zn7xN_UNTYPED:
4106
354k
    case AARCH64_OPND_SME_Ztx2_STRIDED:
4107
359k
    case AARCH64_OPND_SME_Ztx4_STRIDED:
4108
359k
      print_register_list (buf, size, opnd, "z", styler);
4109
359k
      break;
4110
4111
467
    case AARCH64_OPND_SVE_Zm1_23_INDEX:
4112
1.64k
    case AARCH64_OPND_SVE_Zm2_22_INDEX:
4113
7.01k
    case AARCH64_OPND_SVE_Zm3_INDEX:
4114
17.1k
    case AARCH64_OPND_SVE_Zm3_22_INDEX:
4115
17.9k
    case AARCH64_OPND_SVE_Zm3_19_INDEX:
4116
18.9k
    case AARCH64_OPND_SVE_Zm3_12_INDEX:
4117
25.5k
    case AARCH64_OPND_SVE_Zm3_11_INDEX:
4118
29.2k
    case AARCH64_OPND_SVE_Zm3_10_INDEX:
4119
32.8k
    case AARCH64_OPND_SVE_Zm4_11_INDEX:
4120
38.7k
    case AARCH64_OPND_SVE_Zm4_INDEX:
4121
39.6k
    case AARCH64_OPND_SVE_Zn_INDEX:
4122
44.6k
    case AARCH64_OPND_SME_Zk_INDEX:
4123
45.0k
    case AARCH64_OPND_SME_Zm_INDEX1:
4124
47.9k
    case AARCH64_OPND_SME_Zm_INDEX2:
4125
48.4k
    case AARCH64_OPND_SME_Zm_INDEX2_3:
4126
50.4k
    case AARCH64_OPND_SME_Zm_INDEX3_1:
4127
53.2k
    case AARCH64_OPND_SME_Zm_INDEX3_2:
4128
54.0k
    case AARCH64_OPND_SME_Zm_INDEX3_3:
4129
58.9k
    case AARCH64_OPND_SME_Zm_INDEX3_10:
4130
59.3k
    case AARCH64_OPND_SVE_Zn_5_INDEX:
4131
61.3k
    case AARCH64_OPND_SME_Zm_INDEX4_1:
4132
62.5k
    case AARCH64_OPND_SME_Zm_INDEX4_2:
4133
78.7k
    case AARCH64_OPND_SME_Zm_INDEX4_3:
4134
85.2k
    case AARCH64_OPND_SME_Zm_INDEX4_10:
4135
85.5k
    case AARCH64_OPND_SME_Zn_INDEX1_16:
4136
85.8k
    case AARCH64_OPND_SME_Zn_INDEX2_15:
4137
86.5k
    case AARCH64_OPND_SME_Zn_INDEX2_16:
4138
86.6k
    case AARCH64_OPND_SME_Zn_INDEX2_19:
4139
86.8k
    case AARCH64_OPND_SME_Zn_INDEX3_14:
4140
87.0k
    case AARCH64_OPND_SME_Zn_INDEX3_15:
4141
87.2k
    case AARCH64_OPND_SME_Zn_INDEX4_14:
4142
87.2k
      snprintf (buf, size, "%s[%s]",
4143
87.2k
    (opnd->qualifier == AARCH64_OPND_QLF_NIL
4144
87.2k
     ? style_reg (styler, "z%d", opnd->reglane.regno)
4145
87.2k
     : style_reg (styler, "z%d.%s", opnd->reglane.regno,
4146
77.7k
            aarch64_get_qualifier_name (opnd->qualifier))),
4147
87.2k
    style_imm (styler, "%" PRIi64, opnd->reglane.index));
4148
87.2k
      break;
4149
4150
84
    case AARCH64_OPND_SVE_Zn0_INDEX:
4151
169
    case AARCH64_OPND_SVE_Zn1_17_INDEX:
4152
235
    case AARCH64_OPND_SVE_Zn2_18_INDEX:
4153
509
    case AARCH64_OPND_SVE_Zn3_22_INDEX:
4154
598
    case AARCH64_OPND_SVE_Zd0_INDEX:
4155
702
    case AARCH64_OPND_SVE_Zd1_17_INDEX:
4156
783
    case AARCH64_OPND_SVE_Zd2_18_INDEX:
4157
853
    case AARCH64_OPND_SVE_Zd3_22_INDEX:
4158
853
      if (opnd->reglane.index == 0)
4159
257
  snprintf (buf, size, "%s", style_reg (styler, "z%d", opnd->reg.regno));
4160
596
      else
4161
596
  snprintf (buf, size, "%s[%s]",
4162
596
      style_reg (styler, "z%d", opnd->reglane.regno),
4163
596
      style_imm (styler, "%" PRIi64, opnd->reglane.index));
4164
853
      break;
4165
4166
2.10k
    case AARCH64_OPND_SME_ZAda_1b:
4167
75.0k
    case AARCH64_OPND_SME_ZAda_2b:
4168
93.9k
    case AARCH64_OPND_SME_ZAda_3b:
4169
93.9k
      snprintf (buf, size, "%s",
4170
93.9k
    style_reg (styler, "za%d.%s", opnd->reg.regno,
4171
93.9k
         aarch64_get_qualifier_name (opnd->qualifier)));
4172
93.9k
      break;
4173
4174
726
    case AARCH64_OPND_SME_ZA_HV_idx_src:
4175
3.18k
    case AARCH64_OPND_SME_ZA_HV_idx_srcxN:
4176
44.3k
    case AARCH64_OPND_SME_ZA_HV_idx_dest:
4177
45.3k
    case AARCH64_OPND_SME_ZA_HV_idx_destxN:
4178
92.4k
    case AARCH64_OPND_SME_ZA_HV_idx_ldstr:
4179
92.5k
    case AARCH64_OPND_SME_ZA_array_vrsb_1:
4180
92.6k
    case AARCH64_OPND_SME_ZA_array_vrsh_1:
4181
92.7k
    case AARCH64_OPND_SME_ZA_array_vrss_1:
4182
93.0k
    case AARCH64_OPND_SME_ZA_array_vrsd_1:
4183
93.3k
    case AARCH64_OPND_SME_ZA_array_vrsb_2:
4184
93.4k
    case AARCH64_OPND_SME_ZA_array_vrsh_2:
4185
93.6k
    case AARCH64_OPND_SME_ZA_array_vrss_2:
4186
94.0k
    case AARCH64_OPND_SME_ZA_array_vrsd_2:
4187
94.9k
    case AARCH64_OPND_SME_ZA_ARRAY4:
4188
94.9k
      snprintf (buf, size, "%s%s[%s, %s%s%s%s%s]%s",
4189
94.9k
    opnd->type == AARCH64_OPND_SME_ZA_HV_idx_ldstr ? "{" : "",
4190
94.9k
    style_reg (styler, "za%d%c%s%s",
4191
94.9k
         opnd->indexed_za.regno,
4192
94.9k
         opnd->indexed_za.v == 1 ? 'v' : 'h',
4193
94.9k
         opnd->qualifier == AARCH64_OPND_QLF_NIL ? "" : ".",
4194
94.9k
         (opnd->qualifier == AARCH64_OPND_QLF_NIL
4195
94.9k
          ? ""
4196
94.9k
          : aarch64_get_qualifier_name (opnd->qualifier))),
4197
94.9k
    style_reg (styler, "w%d", opnd->indexed_za.index.regno),
4198
94.9k
    style_imm (styler, "%" PRIi64, opnd->indexed_za.index.imm),
4199
94.9k
    opnd->indexed_za.index.countm1 ? ":" : "",
4200
94.9k
    (opnd->indexed_za.index.countm1
4201
94.9k
     ? style_imm (styler, "%d",
4202
5.06k
            opnd->indexed_za.index.imm
4203
5.06k
            + opnd->indexed_za.index.countm1)
4204
94.9k
     : ""),
4205
94.9k
    opnd->indexed_za.group_size ? ", " : "",
4206
94.9k
    opnd->indexed_za.group_size == 2
4207
94.9k
    ? style_sub_mnem (styler, "vgx2")
4208
94.9k
    : opnd->indexed_za.group_size == 4
4209
94.9k
    ? style_sub_mnem (styler, "vgx4") : "",
4210
94.9k
    opnd->type == AARCH64_OPND_SME_ZA_HV_idx_ldstr ? "}" : "");
4211
94.9k
      break;
4212
4213
292
    case AARCH64_OPND_SME_list_of_64bit_tiles:
4214
292
      print_sme_za_list (buf, size, opnd->imm.value, styler);
4215
292
      break;
4216
4217
6.49k
    case AARCH64_OPND_SME_ZA_array_off1x4:
4218
12.3k
    case AARCH64_OPND_SME_ZA_array_off2x2:
4219
20.1k
    case AARCH64_OPND_SME_ZA_array_off2x4:
4220
31.0k
    case AARCH64_OPND_SME_ZA_array_off3_0:
4221
31.3k
    case AARCH64_OPND_SME_ZA_array_off3_5:
4222
52.5k
    case AARCH64_OPND_SME_ZA_array_off3x2:
4223
53.5k
    case AARCH64_OPND_SME_ZA_array_off4:
4224
53.5k
      snprintf (buf, size, "%s[%s, %s%s%s%s%s]",
4225
53.5k
    style_reg (styler, "za%s%s",
4226
53.5k
         opnd->qualifier == AARCH64_OPND_QLF_NIL ? "" : ".",
4227
53.5k
         (opnd->qualifier == AARCH64_OPND_QLF_NIL
4228
53.5k
          ? ""
4229
53.5k
          : aarch64_get_qualifier_name (opnd->qualifier))),
4230
53.5k
    style_reg (styler, "w%d", opnd->indexed_za.index.regno),
4231
53.5k
    style_imm (styler, "%" PRIi64, opnd->indexed_za.index.imm),
4232
53.5k
    opnd->indexed_za.index.countm1 ? ":" : "",
4233
53.5k
    (opnd->indexed_za.index.countm1
4234
53.5k
     ? style_imm (styler, "%d",
4235
41.3k
            opnd->indexed_za.index.imm
4236
41.3k
            + opnd->indexed_za.index.countm1)
4237
53.5k
     : ""),
4238
53.5k
    opnd->indexed_za.group_size ? ", " : "",
4239
53.5k
    opnd->indexed_za.group_size == 2
4240
53.5k
    ? style_sub_mnem (styler, "vgx2")
4241
53.5k
    : opnd->indexed_za.group_size == 4
4242
39.4k
    ? style_sub_mnem (styler, "vgx4") : "");
4243
53.5k
      break;
4244
4245
0
    case AARCH64_OPND_SME_SM_ZA:
4246
0
      snprintf (buf, size, "%s",
4247
0
    style_reg (styler, opnd->reg.regno == 's' ? "sm" : "za"));
4248
0
      break;
4249
4250
5.19k
    case AARCH64_OPND_SME_PnT_Wm_imm:
4251
5.19k
      snprintf (buf, size, "%s[%s, %s]",
4252
5.19k
    style_reg (styler, "p%d.%s", opnd->indexed_za.regno,
4253
5.19k
         aarch64_get_qualifier_name (opnd->qualifier)),
4254
5.19k
    style_reg (styler, "w%d", opnd->indexed_za.index.regno),
4255
5.19k
    style_imm (styler, "%" PRIi64, opnd->indexed_za.index.imm));
4256
5.19k
      break;
4257
4258
48
    case AARCH64_OPND_SME_VLxN_10:
4259
2.78k
    case AARCH64_OPND_SME_VLxN_13:
4260
2.78k
      enum_value = opnd->imm.value;
4261
2.78k
      assert (enum_value < ARRAY_SIZE (aarch64_sme_vlxn_array));
4262
2.78k
      snprintf (buf, size, "%s",
4263
2.78k
    style_sub_mnem (styler, aarch64_sme_vlxn_array[enum_value]));
4264
2.78k
      break;
4265
4266
77
    case AARCH64_OPND_BRBOP:
4267
77
      enum_value = opnd->imm.value;
4268
77
      assert (enum_value < ARRAY_SIZE (aarch64_brbop_array));
4269
77
      snprintf (buf, size, "%s",
4270
77
    style_sub_mnem (styler, aarch64_brbop_array[enum_value]));
4271
77
      break;
4272
4273
5.24k
    case AARCH64_OPND_CRn:
4274
10.4k
    case AARCH64_OPND_CRm:
4275
10.4k
      snprintf (buf, size, "%s",
4276
10.4k
    style_reg (styler, "C%" PRIi64, opnd->imm.value));
4277
10.4k
      break;
4278
4279
10.9k
    case AARCH64_OPND_IDX:
4280
11.4k
    case AARCH64_OPND_MASK:
4281
51.8k
    case AARCH64_OPND_IMM:
4282
76.8k
    case AARCH64_OPND_IMM_2:
4283
112k
    case AARCH64_OPND_WIDTH:
4284
117k
    case AARCH64_OPND_UIMM3_OP1:
4285
122k
    case AARCH64_OPND_UIMM3_OP2:
4286
288k
    case AARCH64_OPND_BIT_NUM:
4287
295k
    case AARCH64_OPND_IMM_VLSL:
4288
310k
    case AARCH64_OPND_IMM_VLSR:
4289
310k
    case AARCH64_OPND_SHLL_IMM:
4290
310k
    case AARCH64_OPND_IMM0:
4291
310k
    case AARCH64_OPND_IMMR:
4292
313k
    case AARCH64_OPND_IMMS:
4293
2.16M
    case AARCH64_OPND_UNDEFINED:
4294
2.17M
    case AARCH64_OPND_FBITS:
4295
2.17M
    case AARCH64_OPND_TME_UIMM16:
4296
2.18M
    case AARCH64_OPND_SIMM5:
4297
2.18M
    case AARCH64_OPND_SME_SHRIMM3:
4298
2.18M
    case AARCH64_OPND_SME_SHRIMM4:
4299
2.18M
    case AARCH64_OPND_SME_SHRIMM5:
4300
2.18M
    case AARCH64_OPND_SVE_SHLIMM_PRED:
4301
2.18M
    case AARCH64_OPND_SVE_SHLIMM_UNPRED:
4302
2.18M
    case AARCH64_OPND_SVE_SHLIMM_UNPRED_22:
4303
2.19M
    case AARCH64_OPND_SVE_SHRIMM_PRED:
4304
2.19M
    case AARCH64_OPND_SVE_SHRIMM_UNPRED:
4305
2.19M
    case AARCH64_OPND_SVE_SHRIMM_UNPRED_22:
4306
2.19M
    case AARCH64_OPND_SVE_SIMM5:
4307
2.19M
    case AARCH64_OPND_SVE_SIMM5B:
4308
2.20M
    case AARCH64_OPND_SVE_SIMM6:
4309
2.20M
    case AARCH64_OPND_SVE_SIMM8:
4310
2.20M
    case AARCH64_OPND_SVE_UIMM3:
4311
2.23M
    case AARCH64_OPND_SVE_UIMM7:
4312
2.23M
    case AARCH64_OPND_SVE_UIMM8:
4313
2.23M
    case AARCH64_OPND_SVE_UIMM4:
4314
2.23M
    case AARCH64_OPND_SVE_UIMM8_53:
4315
2.23M
    case AARCH64_OPND_IMM_ROT1:
4316
2.25M
    case AARCH64_OPND_IMM_ROT2:
4317
2.25M
    case AARCH64_OPND_IMM_ROT3:
4318
2.25M
    case AARCH64_OPND_SVE_IMM_ROT1:
4319
2.26M
    case AARCH64_OPND_SVE_IMM_ROT2:
4320
2.26M
    case AARCH64_OPND_SVE_IMM_ROT3:
4321
2.26M
    case AARCH64_OPND_CSSC_SIMM8:
4322
2.27M
    case AARCH64_OPND_CSSC_UIMM8:
4323
2.27M
      snprintf (buf, size, "%s",
4324
2.27M
    style_imm (styler, "#%" PRIi64, opnd->imm.value));
4325
2.27M
      break;
4326
4327
79
    case AARCH64_OPND_SVE_I1_HALF_ONE:
4328
364
    case AARCH64_OPND_SVE_I1_HALF_TWO:
4329
1.57k
    case AARCH64_OPND_SVE_I1_ZERO_ONE:
4330
1.57k
      {
4331
1.57k
  single_conv_t c;
4332
1.57k
  c.i = opnd->imm.value;
4333
1.57k
  snprintf (buf, size, "%s", style_imm (styler, "#%.1f", c.f));
4334
1.57k
  break;
4335
364
      }
4336
4337
427
    case AARCH64_OPND_SVE_PATTERN:
4338
427
      if (optional_operand_p (opcode, idx)
4339
427
    && opnd->imm.value == get_optional_operand_default_value (opcode))
4340
111
  break;
4341
316
      enum_value = opnd->imm.value;
4342
316
      assert (enum_value < ARRAY_SIZE (aarch64_sve_pattern_array));
4343
316
      if (aarch64_sve_pattern_array[enum_value])
4344
133
  snprintf (buf, size, "%s",
4345
133
      style_reg (styler, aarch64_sve_pattern_array[enum_value]));
4346
183
      else
4347
183
  snprintf (buf, size, "%s",
4348
183
      style_imm (styler, "#%" PRIi64, opnd->imm.value));
4349
316
      break;
4350
4351
7.12k
    case AARCH64_OPND_SVE_PATTERN_SCALED:
4352
7.12k
      if (optional_operand_p (opcode, idx)
4353
7.12k
    && !opnd->shifter.operator_present
4354
900
    && opnd->imm.value == get_optional_operand_default_value (opcode))
4355
305
  break;
4356
6.82k
      enum_value = opnd->imm.value;
4357
6.82k
      assert (enum_value < ARRAY_SIZE (aarch64_sve_pattern_array));
4358
6.82k
      if (aarch64_sve_pattern_array[opnd->imm.value])
4359
4.70k
  snprintf (buf, size, "%s",
4360
4.70k
      style_reg (styler,
4361
4.70k
           aarch64_sve_pattern_array[opnd->imm.value]));
4362
2.11k
      else
4363
2.11k
  snprintf (buf, size, "%s",
4364
2.11k
      style_imm (styler, "#%" PRIi64, opnd->imm.value));
4365
6.82k
      if (opnd->shifter.operator_present)
4366
6.22k
  {
4367
6.22k
    size_t len = strlen (buf);
4368
6.22k
    const char *shift_name
4369
6.22k
      = aarch64_operand_modifiers[opnd->shifter.kind].name;
4370
6.22k
    snprintf (buf + len, size - len, ", %s %s",
4371
6.22k
        style_sub_mnem (styler, shift_name),
4372
6.22k
        style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
4373
6.22k
  }
4374
6.82k
      break;
4375
4376
20.8k
    case AARCH64_OPND_SVE_PRFOP:
4377
20.8k
      enum_value = opnd->imm.value;
4378
20.8k
      assert (enum_value < ARRAY_SIZE (aarch64_sve_prfop_array));
4379
20.8k
      if (aarch64_sve_prfop_array[enum_value])
4380
13.5k
  snprintf (buf, size, "%s",
4381
13.5k
      style_reg (styler, aarch64_sve_prfop_array[enum_value]));
4382
7.28k
      else
4383
7.28k
  snprintf (buf, size, "%s",
4384
7.28k
      style_imm (styler, "#%" PRIi64, opnd->imm.value));
4385
20.8k
      break;
4386
4387
66.2k
    case AARCH64_OPND_IMM_MOV:
4388
66.2k
      switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
4389
66.2k
  {
4390
10.8k
  case 4: /* e.g. MOV Wd, #<imm32>.  */
4391
10.8k
      {
4392
10.8k
        int imm32 = opnd->imm.value;
4393
10.8k
        snprintf (buf, size, "%s",
4394
10.8k
      style_imm (styler, "#0x%-20x", imm32));
4395
10.8k
        snprintf (comment, comment_size, "#%d", imm32);
4396
10.8k
      }
4397
10.8k
    break;
4398
55.3k
  case 8: /* e.g. MOV Xd, #<imm64>.  */
4399
55.3k
    snprintf (buf, size, "%s", style_imm (styler, "#0x%-20" PRIx64,
4400
55.3k
            opnd->imm.value));
4401
55.3k
    snprintf (comment, comment_size, "#%" PRIi64, opnd->imm.value);
4402
55.3k
    break;
4403
0
  default:
4404
0
    snprintf (buf, size, "<invalid>");
4405
0
    break;
4406
66.2k
  }
4407
66.2k
      break;
4408
4409
66.2k
    case AARCH64_OPND_FPIMM0:
4410
512
      snprintf (buf, size, "%s", style_imm (styler, "#0.0"));
4411
512
      break;
4412
4413
165k
    case AARCH64_OPND_LIMM:
4414
400k
    case AARCH64_OPND_AIMM:
4415
429k
    case AARCH64_OPND_HALF:
4416
429k
    case AARCH64_OPND_SVE_INV_LIMM:
4417
449k
    case AARCH64_OPND_SVE_LIMM:
4418
452k
    case AARCH64_OPND_SVE_LIMM_MOV:
4419
452k
      if (opnd->shifter.amount)
4420
102k
  snprintf (buf, size, "%s, %s %s",
4421
102k
      style_imm (styler, "#0x%" PRIx64, opnd->imm.value),
4422
102k
      style_sub_mnem (styler, "lsl"),
4423
102k
      style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
4424
350k
      else
4425
350k
  snprintf (buf, size, "%s",
4426
350k
      style_imm (styler, "#0x%" PRIx64, opnd->imm.value));
4427
452k
      break;
4428
4429
725
    case AARCH64_OPND_SIMD_IMM:
4430
4.21k
    case AARCH64_OPND_SIMD_IMM_SFT:
4431
4.21k
      if ((! opnd->shifter.amount && opnd->shifter.kind == AARCH64_MOD_LSL)
4432
2.85k
    || opnd->shifter.kind == AARCH64_MOD_NONE)
4433
2.08k
  snprintf (buf, size, "%s",
4434
2.08k
      style_imm (styler, "#0x%" PRIx64, opnd->imm.value));
4435
2.12k
      else
4436
2.12k
  snprintf (buf, size, "%s, %s %s",
4437
2.12k
      style_imm (styler, "#0x%" PRIx64, opnd->imm.value),
4438
2.12k
      style_sub_mnem (styler, aarch64_operand_modifiers[opnd->shifter.kind].name),
4439
2.12k
      style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
4440
4.21k
      break;
4441
4442
1.34k
    case AARCH64_OPND_SVE_AIMM:
4443
10.0k
    case AARCH64_OPND_SVE_ASIMM:
4444
10.0k
      if (opnd->shifter.amount)
4445
233
  snprintf (buf, size, "%s, %s %s",
4446
233
      style_imm (styler, "#%" PRIi64, opnd->imm.value),
4447
233
      style_sub_mnem (styler, "lsl"),
4448
233
      style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
4449
9.77k
      else
4450
9.77k
  snprintf (buf, size, "%s",
4451
9.77k
      style_imm (styler, "#%" PRIi64, opnd->imm.value));
4452
10.0k
      break;
4453
4454
141
    case AARCH64_OPND_FPIMM:
4455
2.49k
    case AARCH64_OPND_SIMD_FPIMM:
4456
3.49k
    case AARCH64_OPND_SVE_FPIMM8:
4457
3.49k
      switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
4458
3.49k
  {
4459
2.14k
  case 2: /* e.g. FMOV <Hd>, #<imm>.  */
4460
2.14k
      {
4461
2.14k
        half_conv_t c;
4462
2.14k
        c.i = expand_fp_imm (2, opnd->imm.value);
4463
2.14k
        snprintf (buf, size, "%s", style_imm (styler, "#%.18e", c.f));
4464
2.14k
      }
4465
2.14k
    break;
4466
598
  case 4: /* e.g. FMOV <Vd>.4S, #<imm>.  */
4467
598
      {
4468
598
        single_conv_t c;
4469
598
        c.i = expand_fp_imm (4, opnd->imm.value);
4470
598
        snprintf (buf, size, "%s", style_imm (styler, "#%.18e", c.f));
4471
598
      }
4472
598
    break;
4473
754
  case 8: /* e.g. FMOV <Sd>, #<imm>.  */
4474
754
      {
4475
754
        double_conv_t c;
4476
754
        c.i = expand_fp_imm (8, opnd->imm.value);
4477
754
        snprintf (buf, size, "%s", style_imm (styler, "#%.18e", c.d));
4478
754
      }
4479
754
    break;
4480
0
  default:
4481
0
    snprintf (buf, size, "<invalid>");
4482
0
    break;
4483
3.49k
  }
4484
3.49k
      break;
4485
4486
3.49k
    case AARCH64_OPND_CCMP_IMM:
4487
11.3k
    case AARCH64_OPND_NZCV:
4488
12.8k
    case AARCH64_OPND_EXCEPTION:
4489
13.1k
    case AARCH64_OPND_UIMM4:
4490
18.0k
    case AARCH64_OPND_UIMM4_ADDG:
4491
18.1k
    case AARCH64_OPND_UIMM7:
4492
23.0k
    case AARCH64_OPND_UIMM10:
4493
23.0k
      if (optional_operand_p (opcode, idx)
4494
292
    && (opnd->imm.value ==
4495
292
        (int64_t) get_optional_operand_default_value (opcode)))
4496
  /* Omit the operand, e.g. DCPS1.  */
4497
65
  break;
4498
22.9k
      snprintf (buf, size, "%s",
4499
22.9k
    style_imm (styler, "#0x%x", (unsigned int) opnd->imm.value));
4500
22.9k
      break;
4501
4502
20.2k
    case AARCH64_OPND_COND:
4503
20.8k
    case AARCH64_OPND_COND1:
4504
20.8k
      snprintf (buf, size, "%s",
4505
20.8k
    style_sub_mnem (styler, opnd->cond->names[0]));
4506
20.8k
      num_conds = ARRAY_SIZE (opnd->cond->names);
4507
41.5k
      for (i = 1; i < num_conds && opnd->cond->names[i]; ++i)
4508
20.6k
  {
4509
20.6k
    size_t len = comment != NULL ? strlen (comment) : 0;
4510
20.6k
    if (i == 1)
4511
13.6k
      snprintf (comment + len, comment_size - len, "%s = %s",
4512
13.6k
          opnd->cond->names[0], opnd->cond->names[i]);
4513
6.98k
    else
4514
6.98k
      snprintf (comment + len, comment_size - len, ", %s",
4515
6.98k
          opnd->cond->names[i]);
4516
20.6k
  }
4517
20.8k
      break;
4518
4519
159k
    case AARCH64_OPND_ADDR_ADRP:
4520
159k
      addr = ((pc + AARCH64_PCREL_OFFSET) & ~(uint64_t)0xfff)
4521
159k
  + opnd->imm.value;
4522
159k
      if (pcrel_p)
4523
159k
  *pcrel_p = 1;
4524
159k
      if (address)
4525
159k
  *address = addr;
4526
      /* This is not necessary during the disassembling, as print_address_func
4527
   in the disassemble_info will take care of the printing.  But some
4528
   other callers may be still interested in getting the string in *STR,
4529
   so here we do snprintf regardless.  */
4530
159k
      snprintf (buf, size, "%s", style_addr (styler, "#0x%" PRIx64 , addr));
4531
159k
      break;
4532
4533
71.2k
    case AARCH64_OPND_ADDR_PCREL9:
4534
236k
    case AARCH64_OPND_ADDR_PCREL14:
4535
690k
    case AARCH64_OPND_ADDR_PCREL19:
4536
1.04M
    case AARCH64_OPND_ADDR_PCREL21:
4537
1.31M
    case AARCH64_OPND_ADDR_PCREL26:
4538
1.31M
      addr = pc + AARCH64_PCREL_OFFSET + opnd->imm.value;
4539
1.31M
      if (pcrel_p)
4540
1.31M
  *pcrel_p = 1;
4541
1.31M
      if (address)
4542
1.31M
  *address = addr;
4543
      /* This is not necessary during the disassembling, as print_address_func
4544
   in the disassemble_info will take care of the printing.  But some
4545
   other callers may be still interested in getting the string in *STR,
4546
   so here we do snprintf regardless.  */
4547
1.31M
      snprintf (buf, size, "%s", style_addr (styler, "#0x%" PRIx64, addr));
4548
1.31M
      break;
4549
4550
227k
    case AARCH64_OPND_ADDR_SIMPLE:
4551
244k
    case AARCH64_OPND_SIMD_ADDR_SIMPLE:
4552
265k
    case AARCH64_OPND_SIMD_ADDR_POST:
4553
265k
      name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
4554
265k
      if (opnd->type == AARCH64_OPND_SIMD_ADDR_POST)
4555
20.8k
  {
4556
20.8k
    if (opnd->addr.offset.is_reg)
4557
17.5k
      snprintf (buf, size, "[%s], %s",
4558
17.5k
          style_reg (styler, name),
4559
17.5k
          style_reg (styler, "x%d", opnd->addr.offset.regno));
4560
3.25k
    else
4561
3.25k
      snprintf (buf, size, "[%s], %s",
4562
3.25k
          style_reg (styler, name),
4563
3.25k
          style_imm (styler, "#%d", opnd->addr.offset.imm));
4564
20.8k
  }
4565
244k
      else
4566
244k
  snprintf (buf, size, "[%s]", style_reg (styler, name));
4567
265k
      break;
4568
4569
27.1k
    case AARCH64_OPND_ADDR_REGOFF:
4570
40.7k
    case AARCH64_OPND_SVE_ADDR_RR:
4571
47.6k
    case AARCH64_OPND_SVE_ADDR_RR_LSL1:
4572
52.7k
    case AARCH64_OPND_SVE_ADDR_RR_LSL2:
4573
69.6k
    case AARCH64_OPND_SVE_ADDR_RR_LSL3:
4574
85.7k
    case AARCH64_OPND_SVE_ADDR_RR_LSL4:
4575
95.6k
    case AARCH64_OPND_SVE_ADDR_RM:
4576
100k
    case AARCH64_OPND_SVE_ADDR_RM_LSL1:
4577
104k
    case AARCH64_OPND_SVE_ADDR_RM_LSL2:
4578
108k
    case AARCH64_OPND_SVE_ADDR_RM_LSL3:
4579
108k
    case AARCH64_OPND_SVE_ADDR_RM_LSL4:
4580
126k
    case AARCH64_OPND_SVE_ADDR_RX:
4581
136k
    case AARCH64_OPND_SVE_ADDR_RX_LSL1:
4582
147k
    case AARCH64_OPND_SVE_ADDR_RX_LSL2:
4583
152k
    case AARCH64_OPND_SVE_ADDR_RX_LSL3:
4584
157k
    case AARCH64_OPND_SVE_ADDR_RX_LSL4:
4585
157k
      print_register_offset_address
4586
157k
  (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
4587
157k
   get_offset_int_reg_name (opnd), styler);
4588
157k
      break;
4589
4590
16.0k
    case AARCH64_OPND_SVE_ADDR_ZX:
4591
16.0k
      print_register_offset_address
4592
16.0k
  (buf, size, opnd,
4593
16.0k
   get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier),
4594
16.0k
   get_64bit_int_reg_name (opnd->addr.offset.regno, 0), styler);
4595
16.0k
      break;
4596
4597
22.7k
    case AARCH64_OPND_SVE_ADDR_RZ:
4598
25.5k
    case AARCH64_OPND_SVE_ADDR_RZ_LSL1:
4599
28.2k
    case AARCH64_OPND_SVE_ADDR_RZ_LSL2:
4600
31.5k
    case AARCH64_OPND_SVE_ADDR_RZ_LSL3:
4601
37.5k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW_14:
4602
78.9k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW_22:
4603
80.8k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW1_14:
4604
89.1k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW1_22:
4605
90.5k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW2_14:
4606
98.0k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW2_22:
4607
98.6k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW3_14:
4608
106k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW3_22:
4609
106k
      print_register_offset_address
4610
106k
  (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
4611
106k
   get_addr_sve_reg_name (opnd->addr.offset.regno, opnd->qualifier),
4612
106k
   styler);
4613
106k
      break;
4614
4615
564k
    case AARCH64_OPND_ADDR_SIMM7:
4616
681k
    case AARCH64_OPND_ADDR_SIMM9:
4617
692k
    case AARCH64_OPND_ADDR_SIMM10:
4618
718k
    case AARCH64_OPND_ADDR_SIMM11:
4619
728k
    case AARCH64_OPND_ADDR_SIMM13:
4620
735k
    case AARCH64_OPND_RCPC3_ADDR_OFFSET:
4621
759k
    case AARCH64_OPND_ADDR_OFFSET:
4622
759k
    case AARCH64_OPND_RCPC3_ADDR_OPT_POSTIND:
4623
775k
    case AARCH64_OPND_RCPC3_ADDR_OPT_PREIND_WB:
4624
775k
    case AARCH64_OPND_RCPC3_ADDR_POSTIND:
4625
776k
    case AARCH64_OPND_RCPC3_ADDR_PREIND_WB:
4626
777k
    case AARCH64_OPND_SME_ADDR_RI_U4xVL:
4627
778k
    case AARCH64_OPND_SVE_ADDR_RI_S4x16:
4628
780k
    case AARCH64_OPND_SVE_ADDR_RI_S4x32:
4629
842k
    case AARCH64_OPND_SVE_ADDR_RI_S4xVL:
4630
855k
    case AARCH64_OPND_SVE_ADDR_RI_S4x2xVL:
4631
858k
    case AARCH64_OPND_SVE_ADDR_RI_S4x3xVL:
4632
866k
    case AARCH64_OPND_SVE_ADDR_RI_S4x4xVL:
4633
869k
    case AARCH64_OPND_SVE_ADDR_RI_S6xVL:
4634
874k
    case AARCH64_OPND_SVE_ADDR_RI_S9xVL:
4635
880k
    case AARCH64_OPND_SVE_ADDR_RI_U6:
4636
885k
    case AARCH64_OPND_SVE_ADDR_RI_U6x2:
4637
887k
    case AARCH64_OPND_SVE_ADDR_RI_U6x4:
4638
889k
    case AARCH64_OPND_SVE_ADDR_RI_U6x8:
4639
889k
      print_immediate_offset_address
4640
889k
  (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
4641
889k
   styler);
4642
889k
      break;
4643
4644
5.18k
    case AARCH64_OPND_SVE_ADDR_ZI_U5:
4645
11.7k
    case AARCH64_OPND_SVE_ADDR_ZI_U5x2:
4646
14.7k
    case AARCH64_OPND_SVE_ADDR_ZI_U5x4:
4647
16.2k
    case AARCH64_OPND_SVE_ADDR_ZI_U5x8:
4648
16.2k
      print_immediate_offset_address
4649
16.2k
  (buf, size, opnd,
4650
16.2k
   get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier),
4651
16.2k
   styler);
4652
16.2k
      break;
4653
4654
1.00k
    case AARCH64_OPND_SVE_ADDR_ZZ_LSL:
4655
1.29k
    case AARCH64_OPND_SVE_ADDR_ZZ_SXTW:
4656
2.23k
    case AARCH64_OPND_SVE_ADDR_ZZ_UXTW:
4657
2.23k
      print_register_offset_address
4658
2.23k
  (buf, size, opnd,
4659
2.23k
   get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier),
4660
2.23k
   get_addr_sve_reg_name (opnd->addr.offset.regno, opnd->qualifier),
4661
2.23k
   styler);
4662
2.23k
      break;
4663
4664
247k
    case AARCH64_OPND_ADDR_UIMM12:
4665
247k
      name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
4666
247k
      if (opnd->addr.offset.imm)
4667
233k
  snprintf (buf, size, "[%s, %s]",
4668
233k
      style_reg (styler, name),
4669
233k
      style_imm (styler, "#%d", opnd->addr.offset.imm));
4670
14.2k
      else
4671
14.2k
  snprintf (buf, size, "[%s]", style_reg (styler, name));
4672
247k
      break;
4673
4674
11.4k
    case AARCH64_OPND_SYSREG:
4675
13.5k
    case AARCH64_OPND_SYSREG128:
4676
13.5k
      {
4677
13.5k
  int min_mismatch = 999;
4678
13.5k
  int best_index = -1;
4679
13.5k
  uint32_t op_flags = opnd->sysreg.flags;
4680
20.7M
  for (i = 0; aarch64_sys_regs[i].name; ++i)
4681
20.7M
    {
4682
20.7M
      const aarch64_sys_reg *sr = aarch64_sys_regs + i;
4683
4684
20.7M
      if (!(aarch64_sys_regs[i].value == opnd->sysreg.value)
4685
2.12k
    || aarch64_sys_reg_deprecated_p (aarch64_sys_regs[i].flags)
4686
2.12k
    || aarch64_sys_reg_alias_p (aarch64_sys_regs[i].flags))
4687
20.7M
        continue;
4688
4689
2.12k
      int mismatch_score = 0;
4690
2.12k
      if (!AARCH64_CPU_HAS_ALL_FEATURES (features, sr->features))
4691
866
        mismatch_score += 1;
4692
      /* This read/write check only works during disassembly.  During
4693
         assembly the value of op_flags was copied from sr->flags.  */
4694
2.12k
      if (((sr->flags & F_REG_READ) && (op_flags & F_REG_WRITE))
4695
1.90k
    || ((sr->flags & F_REG_WRITE) && (op_flags & F_REG_READ)))
4696
260
        mismatch_score += 2;
4697
4698
2.12k
      if (mismatch_score < min_mismatch)
4699
2.12k
        {
4700
2.12k
    min_mismatch = mismatch_score;
4701
2.12k
    best_index = i;
4702
2.12k
    if (mismatch_score == 0)
4703
998
      break;
4704
2.12k
        }
4705
2.12k
    }
4706
13.5k
  if (best_index == -1)
4707
11.4k
    {
4708
      /* Use encoding-based name for unrecognised system register.  */
4709
11.4k
      unsigned int value = opnd->sysreg.value;
4710
11.4k
      snprintf (buf, size, "%s",
4711
11.4k
          style_reg (styler, "s%u_%u_c%u_c%u_%u",
4712
11.4k
         (value >> 14) & 0x3, (value >> 11) & 0x7,
4713
11.4k
         (value >> 7) & 0xf, (value >> 3) & 0xf,
4714
11.4k
         value & 0x7));
4715
11.4k
    }
4716
2.10k
  else
4717
2.10k
    {
4718
2.10k
      const aarch64_sys_reg *sr = aarch64_sys_regs + best_index;
4719
2.10k
      snprintf (buf, size, "%s", style_reg (styler, sr->name));
4720
4721
      /* Add a note if we violated read/write constraints.  */
4722
2.10k
      if (notes && min_mismatch)
4723
1.10k
        {
4724
1.10k
    if ((sr->flags & F_REG_READ) && (op_flags & F_REG_WRITE))
4725
197
      *notes = _("writing to a read-only register");
4726
909
    else if ((sr->flags & F_REG_WRITE) && (op_flags & F_REG_READ))
4727
43
      *notes = _("reading from a write-only register");
4728
1.10k
        }
4729
2.10k
    }
4730
13.5k
  break;
4731
11.4k
      }
4732
4733
190
    case AARCH64_OPND_PSTATEFIELD:
4734
751
      for (i = 0; aarch64_pstatefields[i].name; ++i)
4735
751
        if (aarch64_pstatefields[i].value == opnd->pstatefield)
4736
190
          {
4737
            /* PSTATEFIELD name is encoded partially in CRm[3:1] for SVCRSM,
4738
               SVCRZA and SVCRSMZA.  */
4739
190
            uint32_t flags = aarch64_pstatefields[i].flags;
4740
190
            if (flags & F_REG_IN_CRM
4741
0
                && (PSTATE_DECODE_CRM (opnd->sysreg.flags)
4742
0
                    != PSTATE_DECODE_CRM (flags)))
4743
0
              continue;
4744
190
            break;
4745
190
          }
4746
190
      assert (aarch64_pstatefields[i].name);
4747
190
      snprintf (buf, size, "%s",
4748
190
    style_reg (styler, aarch64_pstatefields[i].name));
4749
190
      break;
4750
4751
140
    case AARCH64_OPND_GIC:
4752
140
    case AARCH64_OPND_GICR:
4753
140
    case AARCH64_OPND_GSB:
4754
261
    case AARCH64_OPND_SYSREG_AT:
4755
430
    case AARCH64_OPND_SYSREG_DC:
4756
430
    case AARCH64_OPND_SYSREG_IC:
4757
655
    case AARCH64_OPND_SYSREG_TLBI:
4758
779
    case AARCH64_OPND_SYSREG_TLBIP:
4759
817
    case AARCH64_OPND_SYSREG_PLBI:
4760
818
    case AARCH64_OPND_SYSREG_SR:
4761
818
      snprintf (buf, size, "%s", style_reg (styler, opnd->sysins_op->name));
4762
818
      break;
4763
4764
94
    case AARCH64_OPND_BARRIER:
4765
264
    case AARCH64_OPND_BARRIER_DSB_NXS:
4766
264
      {
4767
264
  if (opnd->barrier->name[0] == '#')
4768
88
    snprintf (buf, size, "%s", style_imm (styler, opnd->barrier->name));
4769
176
  else
4770
176
    snprintf (buf, size, "%s",
4771
176
        style_sub_mnem (styler, opnd->barrier->name));
4772
264
      }
4773
264
      break;
4774
4775
187
    case AARCH64_OPND_BARRIER_ISB:
4776
      /* Operand can be omitted, e.g. in DCPS1.  */
4777
187
      if (! optional_operand_p (opcode, idx)
4778
187
    || (opnd->barrier->value
4779
187
        != get_optional_operand_default_value (opcode)))
4780
44
  snprintf (buf, size, "%s",
4781
44
      style_imm (styler, "#0x%x", opnd->barrier->value));
4782
187
      break;
4783
4784
45.3k
    case AARCH64_OPND_PRFOP:
4785
45.3k
      if ((opnd->prfop->name == NULL)
4786
39.5k
          || (opcode->iclass != ldst_pos && opnd->prfop->value == 0x18))
4787
18.6k
        snprintf (buf, size, "%s",
4788
18.6k
                  style_imm (styler, "#0x%02x", opnd->prfop->value));
4789
26.7k
      else
4790
26.7k
        snprintf (buf, size, "%s", style_sub_mnem (styler, opnd->prfop->name));
4791
45.3k
      break;
4792
4793
748
    case AARCH64_OPND_RPRFMOP:
4794
748
      enum_value = opnd->imm.value;
4795
748
      if (enum_value < ARRAY_SIZE (aarch64_rprfmop_array)
4796
748
    && aarch64_rprfmop_array[enum_value])
4797
123
  snprintf (buf, size, "%s",
4798
123
      style_reg (styler, aarch64_rprfmop_array[enum_value]));
4799
625
      else
4800
625
  snprintf (buf, size, "%s",
4801
625
      style_imm (styler, "#%" PRIi64, opnd->imm.value));
4802
748
      break;
4803
4804
126
    case AARCH64_OPND_BARRIER_PSB:
4805
126
      snprintf (buf, size, "%s", style_sub_mnem (styler, "csync"));
4806
126
      break;
4807
4808
0
    case AARCH64_OPND_X16:
4809
0
      snprintf (buf, size, "%s", style_reg (styler, "x16"));
4810
0
      break;
4811
4812
2.01k
    case AARCH64_OPND_SME_ZT0:
4813
2.01k
      snprintf (buf, size, "%s", style_reg (styler, "zt0"));
4814
2.01k
      break;
4815
4816
120
    case AARCH64_OPND_SME_ZT0_INDEX:
4817
120
      snprintf (buf, size, "%s[%s]", style_reg (styler, "zt0"),
4818
120
    style_imm (styler, "%d", (int) opnd->imm.value));
4819
120
      break;
4820
162
    case AARCH64_OPND_SME_ZT0_INDEX_MUL_VL:
4821
162
      snprintf (buf, size, "%s[%s, %s]", style_reg (styler, "zt0"),
4822
162
    style_imm (styler, "%d", (int) opnd->imm.value),
4823
162
    style_sub_mnem (styler, "mul vl"));
4824
162
      break;
4825
4826
47
    case AARCH64_OPND_SME_ZT0_LIST:
4827
47
      snprintf (buf, size, "{%s}", style_reg (styler, "zt0"));
4828
47
      break;
4829
4830
0
    case AARCH64_OPND_BARRIER_GCSB:
4831
0
      snprintf (buf, size, "%s", style_sub_mnem (styler, "dsync"));
4832
0
      break;
4833
4834
1
    case AARCH64_OPND_NOT_BALANCED_10:
4835
426
    case AARCH64_OPND_NOT_BALANCED_17:
4836
426
      if (opnd->imm.value)
4837
64
  snprintf (buf, size, "%s", style_sub_mnem (styler, "nb"));
4838
426
      break;
4839
4840
235
    case AARCH64_OPND_BTI_TARGET:
4841
235
      snprintf (buf, size, "%s",
4842
235
    style_sub_mnem (styler, opnd->hint_option->name));
4843
235
      break;
4844
4845
109
    case AARCH64_OPND_STSHH_POLICY:
4846
109
      snprintf (buf, size, "%s", style_sub_mnem (styler, opnd->hint_option->name));
4847
109
      break;
4848
4849
0
    case AARCH64_OPND_SHUH_PHINT:
4850
0
      if (*(opnd->hint_option->name))
4851
0
  snprintf (buf, size, "%s",
4852
0
      style_sub_mnem (styler, opnd->hint_option->name));
4853
0
      break;
4854
4855
9.57k
    case AARCH64_OPND_MOPS_ADDR_Rd:
4856
17.6k
    case AARCH64_OPND_MOPS_ADDR_Rs:
4857
17.6k
      snprintf (buf, size, "[%s]!",
4858
17.6k
    style_reg (styler,
4859
17.6k
         get_int_reg_name (opnd->reg.regno,
4860
17.6k
               AARCH64_OPND_QLF_X, 0)));
4861
17.6k
      break;
4862
4863
9.57k
    case AARCH64_OPND_MOPS_WB_Rn:
4864
9.57k
      snprintf (buf, size, "%s!",
4865
9.57k
    style_reg (styler, get_int_reg_name (opnd->reg.regno,
4866
9.57k
                 AARCH64_OPND_QLF_X, 0)));
4867
9.57k
      break;
4868
4869
0
    default:
4870
0
      snprintf (buf, size, "<invalid>");
4871
0
      break;
4872
15.9M
    }
4873
15.9M
}
4874

4875
#define CPENC(op0,op1,crn,crm,op2) \
4876
  ((((op0) << 19) | ((op1) << 16) | ((crn) << 12) | ((crm) << 8) | ((op2) << 5)) >> 5)
4877
  /* for 3.9.3 Instructions for Accessing Special Purpose Registers */
4878
#define CPEN_(op1,crm,op2) CPENC(3,(op1),4,(crm),(op2))
4879
  /* for 3.9.10 System Instructions */
4880
#define CPENS(op1,crn,crm,op2) CPENC(1,(op1),(crn),(crm),(op2))
4881
4882
#define C0  0
4883
#define C1  1
4884
#define C2  2
4885
#define C3  3
4886
#define C4  4
4887
#define C5  5
4888
#define C6  6
4889
#define C7  7
4890
#define C8  8
4891
#define C9  9
4892
#define C10 10
4893
#define C11 11
4894
#define C12 12
4895
#define C13 13
4896
#define C14 14
4897
#define C15 15
4898
4899
/* TODO there is one more issues need to be resolved
4900
   1. handle cpu-implementation-defined system registers.
4901
4902
   Note that the F_REG_{READ,WRITE} flags mean read-only and write-only
4903
   respectively.  If neither of these are set then the register is read-write.  */
4904
const aarch64_sys_reg aarch64_sys_regs [] =
4905
{
4906
  #define SYSREG(name, encoding, flags, features) \
4907
    { name, encoding, flags, features },
4908
  #include "aarch64-sys-regs.def"
4909
  { 0, CPENC (0,0,0,0,0), 0, AARCH64_NO_FEATURES }
4910
  #undef SYSREG
4911
};
4912
4913
bool
4914
aarch64_sys_reg_deprecated_p (const uint32_t reg_flags)
4915
2.12k
{
4916
2.12k
  return (reg_flags & F_DEPRECATED) != 0;
4917
2.12k
}
4918
4919
bool
4920
aarch64_sys_reg_128bit_p (const uint32_t reg_flags)
4921
0
{
4922
0
  return (reg_flags & F_REG_128) != 0;
4923
0
}
4924
4925
bool
4926
aarch64_sys_reg_alias_p (const uint32_t reg_flags)
4927
2.12k
{
4928
2.12k
  return (reg_flags & F_REG_ALIAS) != 0;
4929
2.12k
}
4930
4931
/* The CPENC below is fairly misleading, the fields
4932
   here are not in CPENC form. They are in op2op1 form. The fields are encoded
4933
   by ins_pstatefield, which just shifts the value by the width of the fields
4934
   in a loop. So if you CPENC them only the first value will be set, the rest
4935
   are masked out to 0. As an example. op2 = 3, op1=2. CPENC would produce a
4936
   value of 0b110000000001000000 (0x30040) while what you want is
4937
   0b011010 (0x1a).  */
4938
const aarch64_sys_reg aarch64_pstatefields [] =
4939
{
4940
  { "spsel",  0x05, F_REG_MAX_VALUE (1), AARCH64_NO_FEATURES },
4941
  { "daifset",  0x1e, F_REG_MAX_VALUE (15), AARCH64_NO_FEATURES },
4942
  { "daifclr",  0x1f, F_REG_MAX_VALUE (15), AARCH64_NO_FEATURES },
4943
  { "pan",  0x04, F_REG_MAX_VALUE (1), AARCH64_FEATURE (PAN) },
4944
  { "uao",  0x03, F_REG_MAX_VALUE (1), AARCH64_FEATURE (V8_2A) },
4945
  { "ssbs", 0x19, F_REG_MAX_VALUE (1), AARCH64_FEATURE (SSBS) },
4946
  { "dit",  0x1a, F_REG_MAX_VALUE (1), AARCH64_FEATURE (V8_4A) },
4947
  { "tco",  0x1c, F_REG_MAX_VALUE (1), AARCH64_FEATURE (MEMTAG) },
4948
  { "svcrsm", 0x1b, PSTATE_ENCODE_CRM_AND_IMM (0x2,0x1) | F_REG_MAX_VALUE (1),
4949
    AARCH64_FEATURE (SME) },
4950
  { "svcrza", 0x1b, PSTATE_ENCODE_CRM_AND_IMM (0x4,0x1) | F_REG_MAX_VALUE (1),
4951
    AARCH64_FEATURE (SME) },
4952
  { "svcrsmza", 0x1b, PSTATE_ENCODE_CRM_AND_IMM (0x6,0x1) | F_REG_MAX_VALUE (1),
4953
    AARCH64_FEATURE (SME) },
4954
  { "allint", 0x08, F_REG_MAX_VALUE (1), AARCH64_FEATURE (V8_8A) },
4955
  { 0,  CPENC (0,0,0,0,0), 0, AARCH64_NO_FEATURES },
4956
};
4957
4958
bool
4959
aarch64_pstatefield_supported_p (const aarch64_feature_set features,
4960
         const aarch64_sys_reg *reg)
4961
0
{
4962
0
  return AARCH64_CPU_HAS_ALL_FEATURES (features, reg->features);
4963
0
}
4964
4965
const aarch64_sys_ins_reg aarch64_sys_regs_ic[] =
4966
{
4967
    { "ialluis", CPENS(0,C7,C1,0), 0, AARCH64_NO_FEATURES },
4968
    { "iallu",   CPENS(0,C7,C5,0), 0, AARCH64_NO_FEATURES },
4969
    { "ivau",    CPENS (3, C7, C5, 1), F_HASXT, AARCH64_NO_FEATURES },
4970
    { 0, CPENS(0,0,0,0), 0, AARCH64_NO_FEATURES }
4971
};
4972
4973
const aarch64_sys_ins_reg aarch64_sys_regs_dc[] =
4974
{
4975
    { "zva",      CPENS (3, C7, C4, 1),  F_HASXT, AARCH64_NO_FEATURES },
4976
    { "gva",      CPENS (3, C7, C4, 3),  F_HASXT, AARCH64_FEATURE (MEMTAG) },
4977
    { "gzva",     CPENS (3, C7, C4, 4),  F_HASXT, AARCH64_FEATURE (MEMTAG) },
4978
    { "zgbva",      CPENS (3, C7, C4, 5),  F_HASXT, AARCH64_FEATURE (MTETC) },
4979
    { "gbva",     CPENS (3, C7, C4, 7),  F_HASXT, AARCH64_FEATURE (MTETC) },
4980
    { "ivac",       CPENS (0, C7, C6, 1),  F_HASXT, AARCH64_NO_FEATURES },
4981
    { "igvac",      CPENS (0, C7, C6, 3),  F_HASXT, AARCH64_FEATURE (MEMTAG) },
4982
    { "igsw",       CPENS (0, C7, C6, 4),  F_HASXT, AARCH64_FEATURE (MEMTAG) },
4983
    { "isw",      CPENS (0, C7, C6, 2),  F_HASXT, AARCH64_NO_FEATURES },
4984
    { "igdvac",     CPENS (0, C7, C6, 5),  F_HASXT, AARCH64_FEATURE (MEMTAG) },
4985
    { "igdsw",      CPENS (0, C7, C6, 6),  F_HASXT, AARCH64_FEATURE (MEMTAG) },
4986
    { "cigdvaps",   CPENS (0, C7, C15, 5), F_HASXT, AARCH64_FEATURES (2, MEMTAG, PoPS) },
4987
    { "civaps",     CPENS (0, C7, C15, 1), F_HASXT, AARCH64_FEATURE (PoPS) },
4988
    { "cvac",       CPENS (3, C7, C10, 1), F_HASXT, AARCH64_NO_FEATURES },
4989
    { "cgvac",      CPENS (3, C7, C10, 3), F_HASXT, AARCH64_FEATURE (MEMTAG) },
4990
    { "cgdvac",     CPENS (3, C7, C10, 5), F_HASXT, AARCH64_FEATURE (MEMTAG) },
4991
    { "cvaoc",      CPENS (3, C7, C11, 0), F_HASXT, AARCH64_FEATURE (OCCMO) },
4992
    { "cgdvaoc",    CPENS (3, C7, C11, 7), F_HASXT, AARCH64_FEATURES (2, OCCMO, MEMTAG) },
4993
    { "csw",      CPENS (0, C7, C10, 2), F_HASXT, AARCH64_NO_FEATURES },
4994
    { "cgsw",       CPENS (0, C7, C10, 4), F_HASXT, AARCH64_FEATURE (MEMTAG) },
4995
    { "cgdsw",      CPENS (0, C7, C10, 6), F_HASXT, AARCH64_FEATURE (MEMTAG) },
4996
    { "cvau",       CPENS (3, C7, C11, 1), F_HASXT, AARCH64_NO_FEATURES },
4997
    { "cvap",       CPENS (3, C7, C12, 1), F_HASXT, AARCH64_FEATURE (V8_2A) },
4998
    { "cgvap",      CPENS (3, C7, C12, 3), F_HASXT, AARCH64_FEATURE (MEMTAG) },
4999
    { "cgdvap",     CPENS (3, C7, C12, 5), F_HASXT, AARCH64_FEATURE (MEMTAG) },
5000
    { "cvadp",      CPENS (3, C7, C13, 1), F_HASXT, AARCH64_FEATURE (CVADP) },
5001
    { "cgvadp",     CPENS (3, C7, C13, 3), F_HASXT, AARCH64_FEATURE (MEMTAG) },
5002
    { "cgdvadp",    CPENS (3, C7, C13, 5), F_HASXT, AARCH64_FEATURE (MEMTAG) },
5003
    { "civac",      CPENS (3, C7, C14, 1), F_HASXT, AARCH64_NO_FEATURES },
5004
    { "cigvac",     CPENS (3, C7, C14, 3), F_HASXT, AARCH64_FEATURE (MEMTAG) },
5005
    { "cigdvac",    CPENS (3, C7, C14, 5), F_HASXT, AARCH64_FEATURE (MEMTAG) },
5006
    { "cisw",       CPENS (0, C7, C14, 2), F_HASXT, AARCH64_NO_FEATURES },
5007
    { "cigsw",      CPENS (0, C7, C14, 4), F_HASXT, AARCH64_FEATURE (MEMTAG) },
5008
    { "cigdsw",     CPENS (0, C7, C14, 6), F_HASXT, AARCH64_FEATURE (MEMTAG) },
5009
    { "civaoc",     CPENS (3, C7, C15, 0), F_HASXT, AARCH64_FEATURE (OCCMO) },
5010
    { "cigdvaoc",   CPENS (3, C7, C15, 7), F_HASXT, AARCH64_FEATURES (2, OCCMO, MEMTAG) },
5011
    { "cipae",      CPENS (4, C7, C14, 0), F_HASXT, AARCH64_FEATURE (V8_7A) },
5012
    { "cigdpae",    CPENS (4, C7, C14, 7), F_HASXT, AARCH64_FEATURE (V8_7A) },
5013
    { "cipapa",     CPENS (6, C7, C14, 1), F_HASXT, AARCH64_NO_FEATURES },
5014
    { "cigdpapa",   CPENS (6, C7, C14, 5), F_HASXT, AARCH64_NO_FEATURES },
5015
    { 0,       CPENS(0,0,0,0), 0, AARCH64_NO_FEATURES }
5016
};
5017
5018
const aarch64_sys_ins_reg aarch64_sys_regs_at[] =
5019
{
5020
    { "s1e1r",      CPENS (0, C7, C8, 0), F_HASXT, AARCH64_NO_FEATURES },
5021
    { "s1e1w",      CPENS (0, C7, C8, 1), F_HASXT, AARCH64_NO_FEATURES },
5022
    { "s1e0r",      CPENS (0, C7, C8, 2), F_HASXT, AARCH64_NO_FEATURES },
5023
    { "s1e0w",      CPENS (0, C7, C8, 3), F_HASXT, AARCH64_NO_FEATURES },
5024
    { "s12e1r",     CPENS (4, C7, C8, 4), F_HASXT, AARCH64_NO_FEATURES },
5025
    { "s12e1w",     CPENS (4, C7, C8, 5), F_HASXT, AARCH64_NO_FEATURES },
5026
    { "s12e0r",     CPENS (4, C7, C8, 6), F_HASXT, AARCH64_NO_FEATURES },
5027
    { "s12e0w",     CPENS (4, C7, C8, 7), F_HASXT, AARCH64_NO_FEATURES },
5028
    { "s1e2r",      CPENS (4, C7, C8, 0), F_HASXT, AARCH64_NO_FEATURES },
5029
    { "s1e2w",      CPENS (4, C7, C8, 1), F_HASXT, AARCH64_NO_FEATURES },
5030
    { "s1e3r",      CPENS (6, C7, C8, 0), F_HASXT, AARCH64_NO_FEATURES },
5031
    { "s1e3w",      CPENS (6, C7, C8, 1), F_HASXT, AARCH64_NO_FEATURES },
5032
    { "s1e1rp",     CPENS (0, C7, C9, 0), F_HASXT, AARCH64_FEATURE (V8_2A) },
5033
    { "s1e1wp",     CPENS (0, C7, C9, 1), F_HASXT, AARCH64_FEATURE (V8_2A) },
5034
    { "s1e1a",      CPENS (0, C7, C9, 2), F_HASXT, AARCH64_FEATURE (ATS1A) },
5035
    { "s1e2a",      CPENS (4, C7, C9, 2), F_HASXT, AARCH64_FEATURE (ATS1A) },
5036
    { "s1e3a",      CPENS (6, C7, C9, 2), F_HASXT, AARCH64_FEATURE (ATS1A) },
5037
    { 0,       CPENS(0,0,0,0), 0, AARCH64_NO_FEATURES }
5038
};
5039
5040
const aarch64_sys_ins_reg aarch64_sys_regs_tlbi[] =
5041
{
5042
    { "rpaos",      CPENS (6, C8, C4, 3), F_HASXT, AARCH64_NO_FEATURES },
5043
    { "rpalos",     CPENS (6, C8, C4, 7), F_HASXT, AARCH64_NO_FEATURES },
5044
    { "paallos",    CPENS (6, C8, C1, 4), 0, AARCH64_NO_FEATURES },
5045
    { "paall",      CPENS (6, C8, C7, 4), 0, AARCH64_NO_FEATURES },
5046
5047
#define TLBI_XS_OP(OP, CODE, FLAGS) \
5048
    { OP, CODE, FLAGS,  AARCH64_FEATURE (TLBID)}, \
5049
    { OP "nxs", CODE | CPENS (0, C9, 0, 0), FLAGS, AARCH64_FEATURES (2, XS, TLBID)},
5050
5051
    TLBI_XS_OP ( "vmalle1is", CPENS (0, C8, C3, 0), F_TLBID_XT)
5052
    TLBI_XS_OP ( "vmalls12e1is",CPENS(4,C8, C3, 6), F_TLBID_XT)
5053
    TLBI_XS_OP ( "alle2is",   CPENS (4, C8, C3, 0), F_TLBID_XT)
5054
    TLBI_XS_OP ( "alle1is",   CPENS (4, C8, C3, 4), F_TLBID_XT)
5055
#undef TLBI_XS_OP
5056
5057
#define TLBI_XS_OP(OP, CODE, FLAGS) \
5058
    { OP, CODE, FLAGS,  AARCH64_FEATURE (D128_TLBID)}, \
5059
    { OP "nxs", CODE | CPENS (0, C9, 0, 0), FLAGS, AARCH64_FEATURES (2, XS, D128_TLBID)},
5060
5061
    TLBI_XS_OP ( "vae1is",    CPENS (0, C8, C3, 1), F_HASXT | F_REG_128)
5062
    TLBI_XS_OP ( "vaae1is",   CPENS (0, C8, C3, 3), F_HASXT | F_REG_128)
5063
    TLBI_XS_OP ( "ipas2e1is", CPENS (4, C8, C0, 1), F_HASXT | F_REG_128)
5064
    TLBI_XS_OP ( "ipas2le1is",CPENS (4, C8, C0, 5), F_HASXT | F_REG_128)
5065
    TLBI_XS_OP ( "vale1is",   CPENS (0, C8, C3, 5), F_HASXT | F_REG_128)
5066
    TLBI_XS_OP ( "vaale1is",  CPENS (0, C8, C3, 7), F_HASXT | F_REG_128)
5067
    TLBI_XS_OP ( "vae2is",    CPENS (4, C8, C3, 1), F_HASXT | F_REG_128)
5068
    TLBI_XS_OP ( "vale2is",   CPENS (4, C8, C3, 5), F_HASXT | F_REG_128)
5069
#undef TLBI_XS_OP
5070
5071
#define TLBI_XS_OP(OP, CODE, FLAGS) \
5072
    { OP, CODE, FLAGS,  AARCH64_NO_FEATURES}, \
5073
    { OP "nxs", CODE | CPENS (0, C9, 0, 0), FLAGS, AARCH64_FEATURE (XS)},
5074
5075
    TLBI_XS_OP ( "vmalle1",   CPENS (0, C8, C7, 0), 0)
5076
    TLBI_XS_OP ( "vmalls12e1",CPENS (4, C8, C7, 6), 0)
5077
    TLBI_XS_OP ( "alle2",     CPENS (4, C8, C7, 0), 0)
5078
    TLBI_XS_OP ( "alle1",     CPENS (4, C8, C7, 4), 0)
5079
    TLBI_XS_OP ( "alle3",     CPENS (6, C8, C7, 0), 0)
5080
    TLBI_XS_OP ( "alle3is",   CPENS (6, C8, C3, 0), 0)
5081
#undef TLBI_XS_OP
5082
5083
#define TLBI_XS_OP(OP, CODE, FLAGS) \
5084
    { OP, CODE, FLAGS,  AARCH64_FEATURE (D128)}, \
5085
    { OP "nxs", CODE | CPENS (0, C9, 0, 0), FLAGS, AARCH64_FEATURES (2, XS, D128)},
5086
5087
    TLBI_XS_OP ( "vae1",      CPENS (0, C8, C7, 1), F_HASXT | F_REG_128)
5088
    TLBI_XS_OP ( "aside1",    CPENS (0, C8, C7, 2), F_HASXT)
5089
    TLBI_XS_OP ( "vaae1",     CPENS (0, C8, C7, 3), F_HASXT | F_REG_128)
5090
    TLBI_XS_OP ( "aside1is",  CPENS (0, C8, C3, 2), F_HASXT)
5091
    TLBI_XS_OP ( "ipas2e1",   CPENS (4, C8, C4, 1), F_HASXT | F_REG_128)
5092
    TLBI_XS_OP ( "ipas2le1",  CPENS (4, C8, C4, 5), F_HASXT | F_REG_128)
5093
    TLBI_XS_OP ( "vae2",      CPENS (4, C8, C7, 1), F_HASXT | F_REG_128)
5094
    TLBI_XS_OP ( "vae3",      CPENS (6, C8, C7, 1), F_HASXT | F_REG_128)
5095
    TLBI_XS_OP ( "vae3is",    CPENS (6, C8, C3, 1), F_HASXT | F_REG_128)
5096
    TLBI_XS_OP ( "vale3is",   CPENS (6, C8, C3, 5), F_HASXT | F_REG_128)
5097
    TLBI_XS_OP ( "vale1",     CPENS (0, C8, C7, 5), F_HASXT | F_REG_128)
5098
    TLBI_XS_OP ( "vale2",     CPENS (4, C8, C7, 5), F_HASXT | F_REG_128)
5099
    TLBI_XS_OP ( "vale3",     CPENS (6, C8, C7, 5), F_HASXT | F_REG_128)
5100
    TLBI_XS_OP ( "vaale1",    CPENS (0, C8, C7, 7), F_HASXT | F_REG_128)
5101
#undef TLBI_XS_OP
5102
5103
#define TLBI_XS_OP(OP, CODE, FLAGS) \
5104
    { OP, CODE, FLAGS,  AARCH64_FEATURES (2, V8_4A, TLBID)}, \
5105
    { OP "nxs", CODE | CPENS (0, C9, 0, 0), FLAGS, AARCH64_FEATURES (2, XS, TLBID)},
5106
5107
    TLBI_XS_OP ( "vmalle1os",    CPENS (0, C8, C1, 0), F_TLBID_XT)
5108
    TLBI_XS_OP ( "vmalls12e1os", CPENS (4, C8, C1, 6), F_TLBID_XT)
5109
    TLBI_XS_OP ( "alle2os",      CPENS (4, C8, C1, 0), F_TLBID_XT)
5110
    TLBI_XS_OP ( "alle1os",      CPENS (4, C8, C1, 4), F_TLBID_XT)
5111
    TLBI_XS_OP ( "vmallws2e1is", CPENS (4, C8, C2, 2), F_TLBID_XT)
5112
    TLBI_XS_OP ( "vmallws2e1os", CPENS (4, C8, C5, 2), F_TLBID_XT)
5113
#undef TLBI_XS_OP
5114
5115
#define TLBI_XS_OP(OP, CODE, FLAGS) \
5116
    { OP, CODE, FLAGS,  AARCH64_FEATURES (2, V8_4A, D128_TLBID)}, \
5117
    { OP "nxs", CODE | CPENS (0, C9, 0, 0), FLAGS, AARCH64_FEATURES (2, XS, D128_TLBID)},
5118
5119
    TLBI_XS_OP ( "vae1os",       CPENS (0, C8, C1, 1), F_HASXT | F_REG_128)
5120
    TLBI_XS_OP ( "vaae1os",      CPENS (0, C8, C1, 3), F_HASXT | F_REG_128)
5121
    TLBI_XS_OP ( "vale1os",      CPENS (0, C8, C1, 5), F_HASXT | F_REG_128)
5122
    TLBI_XS_OP ( "vaale1os",     CPENS (0, C8, C1, 7), F_HASXT | F_REG_128)
5123
    TLBI_XS_OP ( "ipas2e1os",    CPENS (4, C8, C4, 0), F_HASXT | F_REG_128)
5124
    TLBI_XS_OP ( "ipas2le1os",   CPENS (4, C8, C4, 4), F_HASXT | F_REG_128)
5125
    TLBI_XS_OP ( "vae2os",       CPENS (4, C8, C1, 1), F_HASXT | F_REG_128)
5126
    TLBI_XS_OP ( "vale2os",      CPENS (4, C8, C1, 5), F_HASXT | F_REG_128)
5127
    TLBI_XS_OP ( "rvae1is",    CPENS (0, C8, C2, 1), F_HASXT | F_REG_128)
5128
    TLBI_XS_OP ( "rvaae1is",   CPENS (0, C8, C2, 3), F_HASXT | F_REG_128)
5129
    TLBI_XS_OP ( "rvale1is",   CPENS (0, C8, C2, 5), F_HASXT | F_REG_128)
5130
    TLBI_XS_OP ( "rvaale1is",  CPENS (0, C8, C2, 7), F_HASXT | F_REG_128)
5131
    TLBI_XS_OP ( "rvae1os",    CPENS (0, C8, C5, 1), F_HASXT | F_REG_128)
5132
    TLBI_XS_OP ( "rvaae1os",   CPENS (0, C8, C5, 3), F_HASXT | F_REG_128)
5133
    TLBI_XS_OP ( "rvale1os",   CPENS (0, C8, C5, 5), F_HASXT | F_REG_128)
5134
    TLBI_XS_OP ( "rvaale1os",  CPENS (0, C8, C5, 7), F_HASXT | F_REG_128)
5135
    TLBI_XS_OP ( "ripas2e1is", CPENS (4, C8, C0, 2), F_HASXT | F_REG_128)
5136
    TLBI_XS_OP ( "ripas2le1is",CPENS (4, C8, C0, 6), F_HASXT | F_REG_128)
5137
    TLBI_XS_OP ( "ripas2e1os", CPENS (4, C8, C4, 3), F_HASXT | F_REG_128)
5138
    TLBI_XS_OP ( "ripas2le1os",CPENS (4, C8, C4, 7), F_HASXT | F_REG_128)
5139
    TLBI_XS_OP ( "rvae2is",    CPENS (4, C8, C2, 1), F_HASXT | F_REG_128)
5140
    TLBI_XS_OP ( "rvale2is",   CPENS (4, C8, C2, 5), F_HASXT | F_REG_128)
5141
    TLBI_XS_OP ( "rvae2os",    CPENS (4, C8, C5, 1), F_HASXT | F_REG_128)
5142
    TLBI_XS_OP ( "rvale2os",   CPENS (4, C8, C5, 5), F_HASXT | F_REG_128)
5143
#undef TLBI_XS_OP
5144
5145
#define TLBI_XS_OP(OP, CODE, FLAGS) \
5146
    { OP, CODE, FLAGS,  AARCH64_FEATURE (V8_4A)}, \
5147
    { OP "nxs", CODE | CPENS (0, C9, 0, 0), FLAGS, AARCH64_FEATURE (XS)},
5148
5149
    TLBI_XS_OP ( "alle3os",      CPENS (6, C8, C1, 0), 0)
5150
    TLBI_XS_OP ( "vmallws2e1",  CPENS (4, C8, C6, 3), 0)
5151
#undef TLBI_XS_OP
5152
5153
#define TLBI_XS_OP(OP, CODE, FLAGS) \
5154
    { OP, CODE, FLAGS,  AARCH64_FEATURES (2, V8_4A, D128)}, \
5155
    { OP "nxs", CODE | CPENS (0, C9, 0, 0), FLAGS, AARCH64_FEATURES (2, XS, D128)},
5156
5157
    TLBI_XS_OP ( "aside1os",     CPENS (0, C8, C1, 2), F_HASXT)
5158
    TLBI_XS_OP ( "vae3os",       CPENS (6, C8, C1, 1), F_HASXT | F_REG_128 )
5159
    TLBI_XS_OP ( "vale3os",      CPENS (6, C8, C1, 5), F_HASXT | F_REG_128 )
5160
5161
    TLBI_XS_OP ( "rvae1",      CPENS (0, C8, C6, 1), F_HASXT | F_REG_128 )
5162
    TLBI_XS_OP ( "rvaae1",     CPENS (0, C8, C6, 3), F_HASXT | F_REG_128 )
5163
    TLBI_XS_OP ( "rvale1",     CPENS (0, C8, C6, 5), F_HASXT | F_REG_128 )
5164
    TLBI_XS_OP ( "rvaale1",    CPENS (0, C8, C6, 7), F_HASXT | F_REG_128 )
5165
    TLBI_XS_OP ( "ripas2e1",   CPENS (4, C8, C4, 2), F_HASXT | F_REG_128 )
5166
    TLBI_XS_OP ( "ripas2le1",  CPENS (4, C8, C4, 6), F_HASXT | F_REG_128 )
5167
    TLBI_XS_OP ( "rvae2",      CPENS (4, C8, C6, 1), F_HASXT | F_REG_128 )
5168
    TLBI_XS_OP ( "rvale2",     CPENS (4, C8, C6, 5), F_HASXT | F_REG_128 )
5169
    TLBI_XS_OP ( "rvae3",      CPENS (6, C8, C6, 1), F_HASXT | F_REG_128 )
5170
    TLBI_XS_OP ( "rvale3",     CPENS (6, C8, C6, 5), F_HASXT | F_REG_128 )
5171
    TLBI_XS_OP ( "rvae3is",    CPENS (6, C8, C2, 1), F_HASXT | F_REG_128 )
5172
    TLBI_XS_OP ( "rvale3is",   CPENS (6, C8, C2, 5), F_HASXT | F_REG_128 )
5173
    TLBI_XS_OP ( "rvae3os",    CPENS (6, C8, C5, 1), F_HASXT | F_REG_128 )
5174
    TLBI_XS_OP ( "rvale3os",   CPENS (6, C8, C5, 5), F_HASXT | F_REG_128 )
5175
#undef TLBI_XS_OP
5176
5177
    { 0,       CPENS(0,0,0,0), 0, AARCH64_NO_FEATURES }
5178
};
5179
5180
const aarch64_sys_ins_reg aarch64_sys_regs_plbi[] =
5181
{
5182
#define PLBI_XS_OP(OP, CODE, FLAGS) \
5183
    { OP, CODE, FLAGS, AARCH64_FEATURES (2, TLBID, POE2) }, \
5184
    { OP "nxs", CODE | CPENS (0, 0, C8, 0), FLAGS, AARCH64_FEATURES (3, TLBID, XS, POE2) },
5185
5186
    PLBI_XS_OP ( "alle1is", CPENS (4, C10, C3, 4),  F_TLBID_XT)
5187
    PLBI_XS_OP ( "alle1os", CPENS (4, C10, C1, 4),  F_TLBID_XT)
5188
    PLBI_XS_OP ( "alle2is", CPENS (4, C10, C3, 0),  F_TLBID_XT)
5189
    PLBI_XS_OP ( "alle2os", CPENS (4, C10, C1, 0),  F_TLBID_XT)
5190
    PLBI_XS_OP ( "vmalle1is", CPENS (0, C10, C3, 0),  F_TLBID_XT)
5191
    PLBI_XS_OP ( "vmalle1os", CPENS (0, C10, C1, 0),  F_TLBID_XT)
5192
5193
#undef PLBI_XS_OP
5194
5195
#define PLBI_XS_OP(OP, CODE, FLAGS) \
5196
    { OP, CODE, FLAGS, AARCH64_FEATURE (POE2) }, \
5197
    { OP "nxs", CODE | CPENS (0, 0, C8, 0), FLAGS, AARCH64_FEATURES (2, POE2, XS) },
5198
5199
    PLBI_XS_OP ( "alle1", CPENS (4, C10, C7, 4),  0 )
5200
    PLBI_XS_OP ( "alle2", CPENS (4, C10, C7, 0),  0 )
5201
    PLBI_XS_OP ( "alle3", CPENS (6, C10, C7, 0),  0 )
5202
    PLBI_XS_OP ( "alle3is", CPENS (6, C10, C3, 0),  0 )
5203
    PLBI_XS_OP ( "alle3os", CPENS (6, C10, C1, 0),  0 )
5204
    PLBI_XS_OP ( "aside1",  CPENS (0, C10, C7, 2),  F_HASXT )
5205
    PLBI_XS_OP ( "aside1is",  CPENS (0, C10, C3, 2),  F_HASXT )
5206
    PLBI_XS_OP ( "aside1os",  CPENS (0, C10, C1, 2),  F_HASXT )
5207
    PLBI_XS_OP ( "permae1", CPENS (0, C10, C7, 3),  F_HASXT )
5208
    PLBI_XS_OP ( "permae1is", CPENS (0, C10, C3, 3),  F_HASXT )
5209
    PLBI_XS_OP ( "permae1os", CPENS (0, C10, C1, 3),  F_HASXT )
5210
    PLBI_XS_OP ( "perme1",  CPENS (0, C10, C7, 1),  F_HASXT )
5211
    PLBI_XS_OP ( "perme1is",  CPENS (0, C10, C3, 1),  F_HASXT )
5212
    PLBI_XS_OP ( "perme1os",  CPENS (0, C10, C1, 1),  F_HASXT )
5213
    PLBI_XS_OP ( "perme2",  CPENS (4, C10, C7, 1),  F_HASXT )
5214
    PLBI_XS_OP ( "perme2is",  CPENS (4, C10, C3, 1),  F_HASXT )
5215
    PLBI_XS_OP ( "perme2os",  CPENS (4, C10, C1, 1),  F_HASXT )
5216
    PLBI_XS_OP ( "perme3",  CPENS (6, C10, C7, 1),  F_HASXT )
5217
    PLBI_XS_OP ( "perme3is",  CPENS (6, C10, C3, 1),  F_HASXT )
5218
    PLBI_XS_OP ( "perme3os",  CPENS (6, C10, C1, 1),  F_HASXT )
5219
    PLBI_XS_OP ( "vmalle1", CPENS (0, C10, C7, 0),  0 )
5220
5221
#undef PLBI_XS_OP
5222
5223
    { 0,  CPENS (0,0,0,0), 0, AARCH64_NO_FEATURES }
5224
};
5225
5226
const aarch64_sys_ins_reg aarch64_sys_ins_gic[] =
5227
{
5228
    { "cdaff", CPENS (0,C12,C1,3), 0, AARCH64_NO_FEATURES },
5229
    { "cddi", CPENS (0,C12,C2,0), 0, AARCH64_NO_FEATURES },
5230
    { "cddis", CPENS (0,C12,C1,0), 0, AARCH64_NO_FEATURES },
5231
    { "cden", CPENS (0,C12,C1,1), 0, AARCH64_NO_FEATURES },
5232
    { "cdeoi", CPENS (0,C12,C1,7), 0, AARCH64_NO_FEATURES },
5233
    { "cdhm", CPENS (0,C12,C2,1), 0, AARCH64_NO_FEATURES },
5234
    { "cdpend", CPENS (0,C12,C1,4), 0, AARCH64_NO_FEATURES },
5235
    { "cdpri", CPENS (0,C12,C1,2), 0, AARCH64_NO_FEATURES },
5236
    { "cdrcfg", CPENS (0,C12,C1,5), 0, AARCH64_NO_FEATURES },
5237
    { "vdaff", CPENS (4,C12,C1,3), 0, AARCH64_NO_FEATURES },
5238
    { "vddi", CPENS (4,C12,C2,0), 0, AARCH64_NO_FEATURES },
5239
    { "vddis", CPENS (4,C12,C1,0), 0, AARCH64_NO_FEATURES },
5240
    { "vden", CPENS (4,C12,C1,1), 0, AARCH64_NO_FEATURES },
5241
    { "vdhm", CPENS (4,C12,C2,1), 0, AARCH64_NO_FEATURES },
5242
    { "vdpend", CPENS (4,C12,C1,4), 0, AARCH64_NO_FEATURES },
5243
    { "vdpri", CPENS (4,C12,C1,2), 0, AARCH64_NO_FEATURES },
5244
    { "vdrcfg", CPENS (4,C12,C1,5), 0, AARCH64_NO_FEATURES },
5245
    { "ldaff", CPENS (6,C12,C1,3), 0, AARCH64_NO_FEATURES },
5246
    { "lddi", CPENS (6,C12,C2,0), 0, AARCH64_NO_FEATURES },
5247
    { "lddis", CPENS (6,C12,C1,0), 0, AARCH64_NO_FEATURES },
5248
    { "lden", CPENS (6,C12,C1,1), 0, AARCH64_NO_FEATURES },
5249
    { "ldhm", CPENS (6,C12,C2,1), 0, AARCH64_NO_FEATURES },
5250
    { "ldpend", CPENS (6,C12,C1,4), 0, AARCH64_NO_FEATURES },
5251
    { "ldpri", CPENS (6,C12,C1,2), 0, AARCH64_NO_FEATURES },
5252
    { "ldrcfg", CPENS (6,C12,C1,5), 0, AARCH64_NO_FEATURES },
5253
    { 0, CPENS (0,0,0,0), 0, AARCH64_NO_FEATURES }
5254
};
5255
5256
const aarch64_sys_ins_reg aarch64_sys_ins_gicr[] =
5257
{
5258
    { "cdia", CPENS (0,C12,C3,0), 0, AARCH64_NO_FEATURES },
5259
    { "cdnmia", CPENS (0,C12,C3,1), 0, AARCH64_NO_FEATURES },
5260
    { 0, CPENS (0,0,0,0), 0, AARCH64_NO_FEATURES }
5261
};
5262
5263
const aarch64_sys_ins_reg aarch64_sys_ins_gsb[] =
5264
{
5265
    { "sys", CPENS (0,C12,0,0), 0, AARCH64_NO_FEATURES },
5266
    { "ack", CPENS (0,C12,0,1), 0, AARCH64_NO_FEATURES },
5267
    { 0, CPENS (0,0,0,0), 0, AARCH64_NO_FEATURES }
5268
};
5269
5270
const aarch64_sys_ins_reg aarch64_sys_regs_sr[] =
5271
{
5272
    /* RCTX is somewhat unique in a way that it has different values
5273
       (op2) based on the instruction in which it is used (cfp/dvp/cpp).
5274
       Thus op2 is masked out and instead encoded directly in the
5275
       aarch64_opcode_table entries for the respective instructions.  */
5276
    { "rctx",   CPENS(3,C7,C3,0), F_HASXT | F_REG_WRITE, AARCH64_FEATURE (PREDRES) }, /* WO */
5277
    { 0,       CPENS(0,0,0,0), 0, AARCH64_NO_FEATURES }
5278
};
5279
5280
bool
5281
aarch64_sys_ins_reg_has_xt (const aarch64_sys_ins_reg *sys_ins_reg)
5282
1.24k
{
5283
1.24k
  return (sys_ins_reg->flags & F_HASXT) != 0;
5284
1.24k
}
5285
5286
bool
5287
aarch64_sys_ins_reg_tlbid_xt (const aarch64_sys_ins_reg *sys_ins_reg)
5288
938
{
5289
938
  return (sys_ins_reg->flags & F_TLBID_XT) != 0;
5290
938
}
5291
5292
extern bool
5293
aarch64_sys_ins_reg_supported_p (const aarch64_feature_set features,
5294
         const char *reg_name,
5295
         const aarch64_feature_set *reg_features)
5296
0
{
5297
  /* Armv8-R has no EL3.  */
5298
0
  if (AARCH64_CPU_HAS_FEATURE (features, V8R))
5299
0
    {
5300
0
      const char *suffix = strrchr (reg_name, '_');
5301
0
      if (suffix && !strcmp (suffix, "_el3"))
5302
0
  return false;
5303
0
    }
5304
5305
0
  return AARCH64_CPU_HAS_ALL_FEATURES (features, *reg_features);
5306
0
}
5307
5308
#undef C0
5309
#undef C1
5310
#undef C2
5311
#undef C3
5312
#undef C4
5313
#undef C5
5314
#undef C6
5315
#undef C7
5316
#undef C8
5317
#undef C9
5318
#undef C10
5319
#undef C11
5320
#undef C12
5321
#undef C13
5322
#undef C14
5323
#undef C15
5324
5325
105k
#define BIT(INSN,BT)     (((INSN) >> (BT)) & 1)
5326
161k
#define BITS(INSN,HI,LO) (((INSN) >> (LO)) & ((1 << (((HI) - (LO)) + 1)) - 1))
5327
5328
static enum err_type
5329
verify_ldpsw (const struct aarch64_inst *inst ATTRIBUTE_UNUSED,
5330
        const aarch64_insn insn, bfd_vma pc ATTRIBUTE_UNUSED,
5331
        bool encoding ATTRIBUTE_UNUSED,
5332
        aarch64_operand_error *mismatch_detail ATTRIBUTE_UNUSED,
5333
        aarch64_instr_sequence *insn_sequence ATTRIBUTE_UNUSED)
5334
53.7k
{
5335
53.7k
  int t  = BITS (insn, 4, 0);
5336
53.7k
  int n  = BITS (insn, 9, 5);
5337
53.7k
  int t2 = BITS (insn, 14, 10);
5338
5339
53.7k
  if (BIT (insn, 23))
5340
16.0k
    {
5341
      /* Write back enabled.  */
5342
16.0k
      if ((t == n || t2 == n) && n != 31)
5343
1.42k
  return ERR_UND;
5344
16.0k
    }
5345
5346
52.2k
  if (BIT (insn, 22))
5347
52.2k
    {
5348
      /* Load */
5349
52.2k
      if (t == t2)
5350
5.04k
  return ERR_UND;
5351
52.2k
    }
5352
5353
47.2k
  return ERR_OK;
5354
52.2k
}
5355
5356
/* Verifier for vector by element 3 operands functions where the
5357
   conditions `if sz:L == 11 then UNDEFINED` holds.  */
5358
5359
static enum err_type
5360
verify_elem_sd (const struct aarch64_inst *inst, const aarch64_insn insn,
5361
    bfd_vma pc ATTRIBUTE_UNUSED, bool encoding,
5362
    aarch64_operand_error *mismatch_detail ATTRIBUTE_UNUSED,
5363
    aarch64_instr_sequence *insn_sequence ATTRIBUTE_UNUSED)
5364
3.30k
{
5365
3.30k
  const aarch64_insn undef_pattern = 0x3;
5366
3.30k
  aarch64_insn value;
5367
5368
3.30k
  assert (inst->opcode);
5369
3.30k
  assert (inst->opcode->operands[2] == AARCH64_OPND_Em);
5370
3.30k
  value = encoding ? inst->value : insn;
5371
3.30k
  assert (value);
5372
5373
3.30k
  if (undef_pattern == extract_fields (value, 0, 2, FLD_sz, FLD_L))
5374
894
    return ERR_UND;
5375
5376
2.40k
  return ERR_OK;
5377
3.30k
}
5378
5379
/* Check an instruction that takes three register operands and that
5380
   requires the register numbers to be distinct from one another.  */
5381
5382
static enum err_type
5383
verify_three_different_regs (const struct aarch64_inst *inst,
5384
           const aarch64_insn insn ATTRIBUTE_UNUSED,
5385
           bfd_vma pc ATTRIBUTE_UNUSED,
5386
           bool encoding ATTRIBUTE_UNUSED,
5387
           aarch64_operand_error *mismatch_detail
5388
             ATTRIBUTE_UNUSED,
5389
           aarch64_instr_sequence *insn_sequence
5390
             ATTRIBUTE_UNUSED)
5391
11.6k
{
5392
11.6k
  int rd, rs, rn;
5393
5394
11.6k
  rd = inst->operands[0].reg.regno;
5395
11.6k
  rs = inst->operands[1].reg.regno;
5396
11.6k
  rn = inst->operands[2].reg.regno;
5397
11.6k
  if (rd == rs || rd == rn || rs == rn)
5398
2.15k
    {
5399
2.15k
      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5400
2.15k
      mismatch_detail->error
5401
2.15k
  = _("the three register operands must be distinct from one another");
5402
2.15k
      mismatch_detail->index = -1;
5403
2.15k
      return ERR_UND;
5404
2.15k
    }
5405
5406
9.44k
  return ERR_OK;
5407
11.6k
}
5408
5409
/* Check an instruction that takes two register operands and that
5410
   requires the register numbers to be distinct from each another.  */
5411
5412
static enum err_type
5413
verify_two_diff_regs (const struct aarch64_inst *inst,
5414
           const aarch64_insn insn ATTRIBUTE_UNUSED,
5415
           bfd_vma pc ATTRIBUTE_UNUSED,
5416
           bool encoding ATTRIBUTE_UNUSED,
5417
           aarch64_operand_error *mismatch_detail
5418
             ATTRIBUTE_UNUSED,
5419
           aarch64_instr_sequence *insn_sequence
5420
             ATTRIBUTE_UNUSED)
5421
219
{
5422
219
  int rd, rn;
5423
5424
219
  rd = inst->operands[0].reg.regno;
5425
219
  rn = inst->operands[1].reg.regno;
5426
219
  if (rd == rn)
5427
87
    {
5428
87
      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5429
87
      mismatch_detail->error
5430
87
  = _("the two register operands must be distinct from each other");
5431
87
      mismatch_detail->index = -1;
5432
87
      return ERR_UND;
5433
87
    }
5434
5435
132
  return ERR_OK;
5436
219
}
5437
5438
/* Add INST to the end of INSN_SEQUENCE.  */
5439
5440
static void
5441
add_insn_to_sequence (const struct aarch64_inst *inst,
5442
          aarch64_instr_sequence *insn_sequence)
5443
9.51k
{
5444
9.51k
  insn_sequence->instr[insn_sequence->num_added_insns++] = *inst;
5445
9.51k
}
5446
5447
/* Initialize an instruction sequence insn_sequence with the instruction INST.
5448
   If INST is NULL the given insn_sequence is cleared and the sequence is left
5449
   uninitialized.  */
5450
5451
void
5452
init_insn_sequence (const struct aarch64_inst *inst,
5453
        aarch64_instr_sequence *insn_sequence)
5454
19.2k
{
5455
19.2k
  int num_req_entries = 0;
5456
5457
19.2k
  if (insn_sequence->instr)
5458
9.12k
    {
5459
9.12k
      XDELETE (insn_sequence->instr);
5460
9.12k
      insn_sequence->instr = NULL;
5461
9.12k
    }
5462
5463
  /* Handle all the cases here.  May need to think of something smarter than
5464
     a giant if/else chain if this grows.  At that time, a lookup table may be
5465
     best.  */
5466
19.2k
  if (inst && inst->opcode->constraints & C_SCAN_MOVPRFX)
5467
3.89k
    num_req_entries = 1;
5468
19.2k
  if (inst && (inst->opcode->constraints & C_SCAN_MOPS_PME) == C_SCAN_MOPS_P)
5469
5.22k
    num_req_entries = 2;
5470
5471
19.2k
  insn_sequence->num_added_insns = 0;
5472
19.2k
  insn_sequence->num_allocated_insns = num_req_entries;
5473
5474
19.2k
  if (num_req_entries != 0)
5475
9.12k
    {
5476
9.12k
      insn_sequence->instr = XCNEWVEC (aarch64_inst, num_req_entries);
5477
9.12k
      add_insn_to_sequence (inst, insn_sequence);
5478
9.12k
    }
5479
19.2k
}
5480
5481
/* Subroutine of verify_constraints.  Check whether the instruction
5482
   is part of a MOPS P/M/E sequence and, if so, whether sequencing
5483
   expectations are met.  Return true if the check passes, otherwise
5484
   describe the problem in MISMATCH_DETAIL.
5485
5486
   IS_NEW_SECTION is true if INST is assumed to start a new section.
5487
   The other arguments are as for verify_constraints.  */
5488
5489
static bool
5490
verify_mops_pme_sequence (const struct aarch64_inst *inst,
5491
        bool is_new_section,
5492
        aarch64_operand_error *mismatch_detail,
5493
        aarch64_instr_sequence *insn_sequence)
5494
262k
{
5495
262k
  const struct aarch64_opcode *opcode;
5496
262k
  const struct aarch64_inst *prev_insn;
5497
262k
  int i;
5498
5499
262k
  opcode = inst->opcode;
5500
262k
  if (insn_sequence->instr)
5501
8.48k
    prev_insn = insn_sequence->instr + (insn_sequence->num_added_insns - 1);
5502
253k
  else
5503
253k
    prev_insn = NULL;
5504
5505
262k
  if (prev_insn
5506
8.48k
      && (prev_insn->opcode->constraints & C_SCAN_MOPS_PME)
5507
4.63k
      && prev_insn->opcode != opcode - 1)
5508
4.25k
    {
5509
4.25k
      mismatch_detail->kind = AARCH64_OPDE_EXPECTED_A_AFTER_B;
5510
4.25k
      mismatch_detail->error = NULL;
5511
4.25k
      mismatch_detail->index = -1;
5512
4.25k
      mismatch_detail->data[0].s = prev_insn->opcode[1].name;
5513
4.25k
      mismatch_detail->data[1].s = prev_insn->opcode->name;
5514
4.25k
      mismatch_detail->non_fatal = true;
5515
4.25k
      return false;
5516
4.25k
    }
5517
5518
257k
  if (opcode->constraints & C_SCAN_MOPS_PME)
5519
4.34k
    {
5520
4.34k
      if (is_new_section || !prev_insn || prev_insn->opcode != opcode - 1)
5521
3.96k
  {
5522
3.96k
    mismatch_detail->kind = AARCH64_OPDE_A_SHOULD_FOLLOW_B;
5523
3.96k
    mismatch_detail->error = NULL;
5524
3.96k
    mismatch_detail->index = -1;
5525
3.96k
    mismatch_detail->data[0].s = opcode->name;
5526
3.96k
    mismatch_detail->data[1].s = opcode[-1].name;
5527
3.96k
    mismatch_detail->non_fatal = true;
5528
3.96k
    return false;
5529
3.96k
  }
5530
5531
820
      for (i = 0; i < 3; ++i)
5532
  /* There's no specific requirement for the data register to be
5533
     the same between consecutive SET* instructions.  */
5534
745
  if ((opcode->operands[i] == AARCH64_OPND_MOPS_ADDR_Rd
5535
360
       || opcode->operands[i] == AARCH64_OPND_MOPS_ADDR_Rs
5536
175
       || opcode->operands[i] == AARCH64_OPND_MOPS_WB_Rn)
5537
745
      && prev_insn->operands[i].reg.regno != inst->operands[i].reg.regno)
5538
310
    {
5539
310
      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5540
310
      if (opcode->operands[i] == AARCH64_OPND_MOPS_ADDR_Rd)
5541
200
        mismatch_detail->error = _("destination register differs from "
5542
110
           "preceding instruction");
5543
110
      else if (opcode->operands[i] == AARCH64_OPND_MOPS_ADDR_Rs)
5544
10
        mismatch_detail->error = _("source register differs from "
5545
100
           "preceding instruction");
5546
100
      else
5547
100
        mismatch_detail->error = _("size register differs from "
5548
310
           "preceding instruction");
5549
310
      mismatch_detail->index = i;
5550
310
      mismatch_detail->non_fatal = true;
5551
310
      return false;
5552
310
    }
5553
385
    }
5554
5555
253k
  return true;
5556
257k
}
5557
5558
/*  This function verifies that the instruction INST adheres to its specified
5559
    constraints.  If it does then ERR_OK is returned, if not then ERR_VFI is
5560
    returned and MISMATCH_DETAIL contains the reason why verification failed.
5561
5562
    The function is called both during assembly and disassembly.  If assembling
5563
    then ENCODING will be TRUE, else FALSE.  If dissassembling PC will be set
5564
    and will contain the PC of the current instruction w.r.t to the section.
5565
5566
    If ENCODING and PC=0 then you are at a start of a section.  The constraints
5567
    are verified against the given state insn_sequence which is updated as it
5568
    transitions through the verification.  */
5569
5570
enum err_type
5571
verify_constraints (const struct aarch64_inst *inst,
5572
        const aarch64_insn insn ATTRIBUTE_UNUSED,
5573
        bfd_vma pc,
5574
        bool encoding,
5575
        aarch64_operand_error *mismatch_detail,
5576
        aarch64_instr_sequence *insn_sequence)
5577
7.11M
{
5578
7.11M
  assert (inst);
5579
7.11M
  assert (inst->opcode);
5580
5581
7.11M
  const struct aarch64_opcode *opcode = inst->opcode;
5582
7.11M
  if (!opcode->constraints && !insn_sequence->instr)
5583
6.84M
    return ERR_OK;
5584
5585
7.11M
  assert (insn_sequence);
5586
5587
271k
  enum err_type res = ERR_OK;
5588
5589
  /* This instruction puts a constraint on the insn_sequence.  */
5590
271k
  if (opcode->flags & F_SCAN)
5591
9.12k
    {
5592
9.12k
      if (insn_sequence->instr)
5593
1.03k
  {
5594
1.03k
    mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5595
1.03k
    mismatch_detail->error = _("instruction opens new dependency "
5596
1.03k
             "sequence without ending previous one");
5597
1.03k
    mismatch_detail->index = -1;
5598
1.03k
    mismatch_detail->non_fatal = true;
5599
1.03k
    res = ERR_VFI;
5600
1.03k
  }
5601
5602
9.12k
      init_insn_sequence (inst, insn_sequence);
5603
9.12k
      return res;
5604
9.12k
    }
5605
5606
271k
  bool is_new_section = (!encoding && pc == 0);
5607
262k
  if (!verify_mops_pme_sequence (inst, is_new_section, mismatch_detail,
5608
262k
         insn_sequence))
5609
8.52k
    {
5610
8.52k
      res = ERR_VFI;
5611
8.52k
      if ((opcode->constraints & C_SCAN_MOPS_PME) != C_SCAN_MOPS_M)
5612
6.27k
  init_insn_sequence (NULL, insn_sequence);
5613
8.52k
    }
5614
5615
  /* Verify constraints on an existing sequence.  */
5616
262k
  if (insn_sequence->instr)
5617
4.24k
    {
5618
4.24k
      const struct aarch64_opcode* inst_opcode = insn_sequence->instr->opcode;
5619
      /* If we're decoding and we hit PC=0 with an open sequence then we haven't
5620
   closed a previous one that we should have.  */
5621
4.24k
      if (is_new_section && res == ERR_OK)
5622
0
  {
5623
0
    mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5624
0
    mismatch_detail->error = _("previous `movprfx' sequence not closed");
5625
0
    mismatch_detail->index = -1;
5626
0
    mismatch_detail->non_fatal = true;
5627
0
    res = ERR_VFI;
5628
    /* Reset the sequence.  */
5629
0
    init_insn_sequence (NULL, insn_sequence);
5630
0
    return res;
5631
0
  }
5632
5633
      /* Validate C_SCAN_MOVPRFX constraints.  Move this to a lookup table.  */
5634
4.24k
      if (inst_opcode->constraints & C_SCAN_MOVPRFX)
5635
3.84k
  {
5636
    /* Check to see if the MOVPRFX SVE instruction is followed by an SVE
5637
       instruction for better error messages.  */
5638
3.84k
    bool sve_operand_p = false;
5639
14.9k
    for (int i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
5640
13.3k
      {
5641
13.3k
        enum aarch64_operand_class op_class
5642
13.3k
    = aarch64_get_operand_class (opcode->operands[i]);
5643
13.3k
        if (op_class == AARCH64_OPND_CLASS_SVE_REG
5644
11.7k
      || op_class == AARCH64_OPND_CLASS_SVE_REGLIST
5645
11.2k
      || op_class == AARCH64_OPND_CLASS_PRED_REG)
5646
2.26k
    {
5647
2.26k
      sve_operand_p = true;
5648
2.26k
      break;
5649
2.26k
    }
5650
13.3k
      }
5651
5652
3.84k
    if (!sve_operand_p)
5653
1.58k
      {
5654
1.58k
        mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5655
1.58k
        mismatch_detail->error = _("SVE instruction expected after "
5656
1.58k
           "`movprfx'");
5657
1.58k
        mismatch_detail->index = -1;
5658
1.58k
        mismatch_detail->non_fatal = true;
5659
1.58k
        res = ERR_VFI;
5660
1.58k
        goto done;
5661
1.58k
      }
5662
5663
    /* Check to see if the MOVPRFX SVE instruction is followed by an SVE
5664
       instruction that is allowed to be used with a MOVPRFX.  */
5665
2.26k
    if (!(opcode->constraints & C_SCAN_MOVPRFX))
5666
761
      {
5667
761
        mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5668
761
        mismatch_detail->error = _("SVE `movprfx' compatible instruction "
5669
761
           "expected");
5670
761
        mismatch_detail->index = -1;
5671
761
        mismatch_detail->non_fatal = true;
5672
761
        res = ERR_VFI;
5673
761
        goto done;
5674
761
      }
5675
5676
    /* Next check for usage of the predicate register.  */
5677
1.50k
    aarch64_opnd_info blk_dest = insn_sequence->instr->operands[0];
5678
1.50k
    aarch64_opnd_info blk_pred, inst_pred;
5679
1.50k
    memset (&blk_pred, 0, sizeof (aarch64_opnd_info));
5680
1.50k
    memset (&inst_pred, 0, sizeof (aarch64_opnd_info));
5681
1.50k
    bool predicated = false;
5682
1.50k
    assert (blk_dest.type == AARCH64_OPND_SVE_Zd);
5683
5684
    /* Determine if the movprfx instruction used is predicated or not.  */
5685
1.50k
    if (insn_sequence->instr->operands[1].type == AARCH64_OPND_SVE_Pg3)
5686
1.40k
      {
5687
1.40k
        predicated = true;
5688
1.40k
        blk_pred = insn_sequence->instr->operands[1];
5689
1.40k
      }
5690
5691
1.50k
    unsigned char max_elem_size = 0;
5692
1.50k
    unsigned char current_elem_size;
5693
1.50k
    int num_op_used = 0, last_op_usage = 0;
5694
1.50k
    int i, inst_pred_idx = -1;
5695
1.50k
    int num_ops = aarch64_num_of_operands (opcode);
5696
6.83k
    for (i = 0; i < num_ops; i++)
5697
5.33k
      {
5698
5.33k
        aarch64_opnd_info inst_op = inst->operands[i];
5699
5.33k
        switch (inst_op.type)
5700
5.33k
    {
5701
1.85k
      case AARCH64_OPND_SVE_Zd:
5702
2.44k
      case AARCH64_OPND_SVE_Zm_5:
5703
2.68k
      case AARCH64_OPND_SVE_Zm_16:
5704
3.29k
      case AARCH64_OPND_SVE_Zn:
5705
3.29k
      case AARCH64_OPND_SVE_Zt:
5706
3.38k
      case AARCH64_OPND_SVE_Vm:
5707
3.49k
      case AARCH64_OPND_SVE_Vn:
5708
3.49k
      case AARCH64_OPND_Va:
5709
3.49k
      case AARCH64_OPND_Vn:
5710
3.49k
      case AARCH64_OPND_Vm:
5711
3.49k
      case AARCH64_OPND_Sn:
5712
3.49k
      case AARCH64_OPND_Sm:
5713
3.49k
        if (inst_op.reg.regno == blk_dest.reg.regno)
5714
836
          {
5715
836
      num_op_used++;
5716
836
      last_op_usage = i;
5717
836
          }
5718
3.49k
        current_elem_size
5719
3.49k
          = aarch64_get_qualifier_esize (inst_op.qualifier);
5720
3.49k
        if (current_elem_size > max_elem_size)
5721
1.50k
          max_elem_size = current_elem_size;
5722
3.49k
        break;
5723
0
      case AARCH64_OPND_SVE_Pd:
5724
1.09k
      case AARCH64_OPND_SVE_Pg3:
5725
1.09k
      case AARCH64_OPND_SVE_Pg4_5:
5726
1.09k
      case AARCH64_OPND_SVE_Pg4_10:
5727
1.16k
      case AARCH64_OPND_SVE_Pg4_16:
5728
1.16k
      case AARCH64_OPND_SVE_Pm:
5729
1.16k
      case AARCH64_OPND_SVE_Pn:
5730
1.16k
      case AARCH64_OPND_SVE_Pt:
5731
1.16k
      case AARCH64_OPND_SME_Pm:
5732
1.16k
        inst_pred = inst_op;
5733
1.16k
        inst_pred_idx = i;
5734
1.16k
        break;
5735
672
      default:
5736
672
        break;
5737
5.33k
    }
5738
5.33k
      }
5739
5740
1.50k
     assert (max_elem_size != 0);
5741
1.50k
     aarch64_opnd_info inst_dest = inst->operands[0];
5742
     /* Determine the size that should be used to compare against the
5743
        movprfx size.  */
5744
1.50k
     current_elem_size
5745
1.50k
       = opcode->constraints & C_MAX_ELEM
5746
1.50k
         ? max_elem_size
5747
1.50k
         : aarch64_get_qualifier_esize (inst_dest.qualifier);
5748
5749
    /* If movprfx is predicated do some extra checks.  */
5750
1.50k
    if (predicated)
5751
1.40k
      {
5752
        /* The instruction must be predicated.  */
5753
1.40k
        if (inst_pred_idx < 0)
5754
341
    {
5755
341
      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5756
341
      mismatch_detail->error = _("predicated instruction expected "
5757
341
               "after `movprfx'");
5758
341
      mismatch_detail->index = -1;
5759
341
      mismatch_detail->non_fatal = true;
5760
341
      res = ERR_VFI;
5761
341
      goto done;
5762
341
    }
5763
5764
        /* The instruction must have a merging predicate.  */
5765
1.06k
        if (inst_pred.qualifier != AARCH64_OPND_QLF_P_M)
5766
34
    {
5767
34
      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5768
34
      mismatch_detail->error = _("merging predicate expected due "
5769
34
               "to preceding `movprfx'");
5770
34
      mismatch_detail->index = inst_pred_idx;
5771
34
      mismatch_detail->non_fatal = true;
5772
34
      res = ERR_VFI;
5773
34
      goto done;
5774
34
    }
5775
5776
        /* The same register must be used in instruction.  */
5777
1.03k
        if (blk_pred.reg.regno != inst_pred.reg.regno)
5778
560
    {
5779
560
      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5780
560
      mismatch_detail->error = _("predicate register differs "
5781
560
               "from that in preceding "
5782
560
               "`movprfx'");
5783
560
      mismatch_detail->index = inst_pred_idx;
5784
560
      mismatch_detail->non_fatal = true;
5785
560
      res = ERR_VFI;
5786
560
      goto done;
5787
560
    }
5788
1.03k
      }
5789
5790
    /* Destructive operations by definition must allow one usage of the
5791
       same register.  */
5792
572
    int allowed_usage
5793
572
      = aarch64_is_destructive_by_operands (opcode) ? 2 : 1;
5794
5795
    /* Operand is not used at all.  */
5796
572
    if (num_op_used == 0)
5797
119
      {
5798
119
        mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5799
119
        mismatch_detail->error = _("output register of preceding "
5800
119
           "`movprfx' not used in current "
5801
119
           "instruction");
5802
119
        mismatch_detail->index = 0;
5803
119
        mismatch_detail->non_fatal = true;
5804
119
        res = ERR_VFI;
5805
119
        goto done;
5806
119
      }
5807
5808
    /* We now know it's used, now determine exactly where it's used.  */
5809
453
    if (blk_dest.reg.regno != inst_dest.reg.regno)
5810
86
      {
5811
86
        mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5812
86
        mismatch_detail->error = _("output register of preceding "
5813
86
           "`movprfx' expected as output");
5814
86
        mismatch_detail->index = 0;
5815
86
        mismatch_detail->non_fatal = true;
5816
86
        res = ERR_VFI;
5817
86
        goto done;
5818
86
      }
5819
5820
    /* Operand used more than allowed for the specific opcode type.  */
5821
367
    if (num_op_used > allowed_usage)
5822
121
      {
5823
121
        mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5824
121
        mismatch_detail->error = _("output register of preceding "
5825
121
           "`movprfx' used as input");
5826
121
        mismatch_detail->index = last_op_usage;
5827
121
        mismatch_detail->non_fatal = true;
5828
121
        res = ERR_VFI;
5829
121
        goto done;
5830
121
      }
5831
5832
    /* Now the only thing left is the qualifiers checks.  The register
5833
       must have the same maximum element size.  */
5834
246
    if (inst_dest.qualifier != AARCH64_OPND_QLF_NIL
5835
246
        && blk_dest.qualifier != AARCH64_OPND_QLF_NIL
5836
148
        && current_elem_size
5837
148
     != aarch64_get_qualifier_esize (blk_dest.qualifier))
5838
44
      {
5839
44
        mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5840
44
        mismatch_detail->error = _("register size not compatible with "
5841
44
           "previous `movprfx'");
5842
44
        mismatch_detail->index = 0;
5843
44
        mismatch_detail->non_fatal = true;
5844
44
        res = ERR_VFI;
5845
44
        goto done;
5846
44
      }
5847
246
  }
5848
5849
4.24k
    done:
5850
4.24k
      if (insn_sequence->num_added_insns == insn_sequence->num_allocated_insns)
5851
  /* We've checked the last instruction in the sequence and so
5852
     don't need the sequence any more.  */
5853
3.85k
  init_insn_sequence (NULL, insn_sequence);
5854
390
      else
5855
390
  add_insn_to_sequence (inst, insn_sequence);
5856
4.24k
    }
5857
5858
262k
  return res;
5859
262k
}
5860
5861
5862
/* Return true if VALUE cannot be moved into an SVE register using DUP
5863
   (with any element size, not just ESIZE) and if using DUPM would
5864
   therefore be OK.  ESIZE is the number of bytes in the immediate.  */
5865
5866
bool
5867
aarch64_sve_dupm_mov_immediate_p (uint64_t uvalue, int esize)
5868
8.98k
{
5869
8.98k
  int64_t svalue = uvalue;
5870
8.98k
  uint64_t upper = (uint64_t) -1 << (esize * 4) << (esize * 4);
5871
5872
8.98k
  if ((uvalue & ~upper) != uvalue && (uvalue | upper) != uvalue)
5873
0
    return false;
5874
8.98k
  if (esize <= 4 || (uint32_t) uvalue == (uint32_t) (uvalue >> 32))
5875
7.27k
    {
5876
7.27k
      svalue = (int32_t) uvalue;
5877
7.27k
      if (esize <= 2 || (uint16_t) uvalue == (uint16_t) (uvalue >> 16))
5878
1.78k
  {
5879
1.78k
    svalue = (int16_t) uvalue;
5880
1.78k
    if (esize == 1 || (uint8_t) uvalue == (uint8_t) (uvalue >> 8))
5881
1.03k
      return false;
5882
1.78k
  }
5883
7.27k
    }
5884
7.94k
  if ((svalue & 0xff) == 0)
5885
3.65k
    svalue /= 256;
5886
7.94k
  return svalue < -128 || svalue >= 128;
5887
8.98k
}
5888
5889
/* Return true if a CPU with the AARCH64_FEATURE_* bits in CPU_VARIANT
5890
   supports the instruction described by INST.  */
5891
5892
bool
5893
aarch64_cpu_supports_inst_p (aarch64_feature_set cpu_variant,
5894
           aarch64_inst *inst)
5895
0
{
5896
0
  if (!inst->opcode->avariant
5897
0
      || !AARCH64_CPU_HAS_ALL_FEATURES (cpu_variant, *inst->opcode->avariant))
5898
0
    return false;
5899
5900
0
  if (inst->opcode->iclass == sme_fp_sd
5901
0
      && inst->operands[0].qualifier == AARCH64_OPND_QLF_S_D
5902
0
      && !AARCH64_CPU_HAS_FEATURE (cpu_variant, SME_F64F64))
5903
0
    return false;
5904
5905
0
  if (inst->opcode->iclass == sme_int_sd
5906
0
      && inst->operands[0].qualifier == AARCH64_OPND_QLF_S_D
5907
0
      && !AARCH64_CPU_HAS_FEATURE (cpu_variant, SME_I16I64))
5908
0
    return false;
5909
5910
0
  return true;
5911
0
}
5912
5913
/* Include the opcode description table as well as the operand description
5914
   table.  */
5915
#define VERIFIER(x) verify_##x
5916
#include "aarch64-tbl.h"