Coverage Report

Created: 2026-09-14 08:07

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
822k
{
132
822k
  return (qualifier >= AARCH64_OPND_QLF_V_8B
133
658k
    && qualifier <= AARCH64_OPND_QLF_V_1Q);
134
822k
}
135
136
static inline bool
137
fp_qualifier_p (enum aarch64_opnd_qualifier qualifier)
138
1.30k
{
139
1.30k
  return (qualifier >= AARCH64_OPND_QLF_S_B
140
1.30k
    && qualifier <= AARCH64_OPND_QLF_S_Q);
141
1.30k
}
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
356k
{
169
356k
  if (vector_qualifier_p (qualifiers[0]))
170
355k
    {
171
      /* e.g. v.4s, v.4s, v.4s
172
     or v.4h, v.4h, v.h[3].  */
173
355k
      if (qualifiers[0] == qualifiers[1]
174
170k
    && vector_qualifier_p (qualifiers[2])
175
122k
    && (aarch64_get_qualifier_esize (qualifiers[0])
176
122k
        == aarch64_get_qualifier_esize (qualifiers[2])))
177
116k
  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
238k
      if (vector_qualifier_p (qualifiers[1])
182
169k
    && aarch64_get_qualifier_esize (qualifiers[0]) != 0
183
169k
    && (aarch64_get_qualifier_esize (qualifiers[0])
184
169k
        == aarch64_get_qualifier_esize (qualifiers[1]) << 1))
185
60.6k
  return DP_VECTOR_LONG;
186
      /* e.g. v.8h, v.8h, v.8b.  */
187
178k
      if (qualifiers[0] == qualifiers[1]
188
54.3k
    && vector_qualifier_p (qualifiers[2])
189
6.21k
    && aarch64_get_qualifier_esize (qualifiers[0]) != 0
190
6.21k
    && (aarch64_get_qualifier_esize (qualifiers[0])
191
6.21k
        == aarch64_get_qualifier_esize (qualifiers[2]) << 1))
192
6.21k
  return DP_VECTOR_WIDE;
193
178k
    }
194
1.30k
  else if (fp_qualifier_p (qualifiers[0]))
195
1.30k
    {
196
      /* e.g. SADDLV <V><d>, <Vn>.<T>.  */
197
1.30k
      if (vector_qualifier_p (qualifiers[1])
198
1.13k
    && (qualifiers[2] == AARCH64_OPND_QLF_UNUSED))
199
1.13k
  return DP_VECTOR_ACROSS_LANES;
200
1.30k
    }
201
202
172k
  return DP_UNKNOWN;
203
356k
}
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
356k
{
216
356k
  return
217
356k
    significant_operand_index [get_data_pattern (opcode->qualifiers_list[0])];
218
356k
}
219

220
enum aarch64_operand_class
221
aarch64_get_operand_class (enum aarch64_opnd type)
222
2.99M
{
223
2.99M
  return aarch64_operands[type].op_class;
224
2.99M
}
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
70.3k
{
264
70.3k
  assert (value < 16);
265
70.3k
  return &aarch64_conds[(unsigned int) value];
266
70.3k
}
267
268
const aarch64_cond *
269
get_inverted_cond (const aarch64_cond *cond)
270
591
{
271
591
  return &aarch64_conds[cond->value ^ 0x1];
272
591
}
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
692k
{
316
692k
  if (extend_p)
317
122k
    return AARCH64_MOD_UXTB + value;
318
569k
  else
319
569k
    return AARCH64_MOD_LSL - value;
320
692k
}
321
322
bool
323
aarch64_extend_operator_p (enum aarch64_modifier_kind kind)
324
60.3k
{
325
60.3k
  return kind > AARCH64_MOD_LSL && kind <= AARCH64_MOD_SXTX;
326
60.3k
}
327
328
static inline bool
329
aarch64_shift_operator_p (enum aarch64_modifier_kind kind)
330
544k
{
331
544k
  return kind >= AARCH64_MOD_ROR && kind <= AARCH64_MOD_LSL;
332
544k
}
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.12M
{
433
3.12M
  return (low <= value) && (value <= high);
434
3.12M
}
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.09M
{
440
2.09M
  return (value % align) == 0;
441
2.09M
}
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.37M
{
447
1.37M
  assert (width < 32);
448
1.37M
  if (width < sizeof (value) * 8)
449
1.37M
    {
450
1.37M
      int64_t lim = (uint64_t) 1 << (width - 1);
451
1.37M
      if (value >= -lim && value < lim)
452
1.37M
  return true;
453
1.37M
    }
454
0
  return false;
455
1.37M
}
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.44M
{
461
2.44M
  assert (width < 32);
462
2.44M
  if (width < sizeof (value) * 8)
463
2.44M
    {
464
2.44M
      int64_t lim = (uint64_t) 1 << width;
465
2.44M
      if (value >= 0 && value < lim)
466
2.44M
  return true;
467
2.44M
    }
468
0
  return false;
469
2.44M
}
470
471
/* Return true if OPERAND is SP or WSP.  */
472
bool
473
aarch64_stack_pointer_p (const aarch64_opnd_info *operand)
474
188k
{
475
188k
  return ((aarch64_get_operand_class (operand->type)
476
188k
     == AARCH64_OPND_CLASS_INT_REG)
477
188k
    && operand_maybe_stack_pointer (aarch64_operands + operand->type)
478
119k
    && operand->reg.regno == 31);
479
188k
}
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.3M
{
581
12.3M
  return aarch64_opnd_qualifiers[qualifier].kind == OQK_OPD_VARIANT;
582
12.3M
}
583
584
static inline bool
585
qualifier_value_in_range_constraint_p (aarch64_opnd_qualifier_t qualifier)
586
4.50M
{
587
4.50M
  return aarch64_opnd_qualifiers[qualifier].kind == OQK_VALUE_IN_RANGE;
588
4.50M
}
589
590
const char*
591
aarch64_get_qualifier_name (aarch64_opnd_qualifier_t qualifier)
592
4.75M
{
593
4.75M
  return aarch64_opnd_qualifiers[qualifier].desc;
594
4.75M
}
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.85M
{
601
8.85M
  assert (operand_variant_qualifier_p (qualifier));
602
8.85M
  return aarch64_opnd_qualifiers[qualifier].data0;
603
8.85M
}
604
605
unsigned char
606
aarch64_get_qualifier_nelem (aarch64_opnd_qualifier_t qualifier)
607
111k
{
608
111k
  assert (operand_variant_qualifier_p (qualifier));
609
111k
  return aarch64_opnd_qualifiers[qualifier].data1;
610
111k
}
611
612
aarch64_insn
613
aarch64_get_qualifier_standard_value (aarch64_opnd_qualifier_t qualifier)
614
3.40M
{
615
3.40M
  assert (operand_variant_qualifier_p (qualifier));
616
3.40M
  return aarch64_opnd_qualifiers[qualifier].data2;
617
3.40M
}
618
619
static int
620
get_lower_bound (aarch64_opnd_qualifier_t qualifier)
621
498k
{
622
498k
  assert (qualifier_value_in_range_constraint_p (qualifier));
623
498k
  return aarch64_opnd_qualifiers[qualifier].data0;
624
498k
}
625
626
static int
627
get_upper_bound (aarch64_opnd_qualifier_t qualifier)
628
533k
{
629
533k
  assert (qualifier_value_in_range_constraint_p (qualifier));
630
533k
  return aarch64_opnd_qualifiers[qualifier].data1;
631
533k
}
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
582
{
677
582
  int i = 0;
678
582
  const enum aarch64_opnd *opnds = opcode->operands;
679
680
582
  if (opnds[0] == AARCH64_OPND_NIL)
681
0
    return false;
682
683
1.66k
  while (opnds[++i] != AARCH64_OPND_NIL)
684
1.41k
    if (opnds[i] == opnds[0])
685
331
      return true;
686
687
251
  return false;
688
582
}
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.3M
{
696
10.3M
  int i = 0;
697
10.3M
  const enum aarch64_opnd *opnds = opcode->operands;
698
35.6M
  while (opnds[i++] != AARCH64_OPND_NIL)
699
25.2M
    ;
700
10.3M
  --i;
701
10.3M
  assert (i >= 0 && i <= AARCH64_MAX_OPND_NUM);
702
10.3M
  return i;
703
10.3M
}
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.29M
{
736
9.29M
  int i, num_opnds, invalid, min_invalid;
737
9.29M
  const aarch64_opnd_qualifier_t *qualifiers;
738
739
9.29M
  num_opnds = aarch64_num_of_operands (inst->opcode);
740
9.29M
  if (num_opnds == 0)
741
96
    {
742
96
      DEBUG_TRACE ("SUCCEED: no operand");
743
96
      *invalid_count = 0;
744
96
      return 1;
745
96
    }
746
747
9.29M
  if (stop_at < 0 || stop_at >= num_opnds)
748
8.12M
    stop_at = num_opnds - 1;
749
750
  /* For each pattern.  */
751
9.29M
  min_invalid = num_opnds;
752
12.8M
  for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i, ++qualifiers_list)
753
12.8M
    {
754
12.8M
      int j;
755
12.8M
      qualifiers = *qualifiers_list;
756
757
      /* Start as positive.  */
758
12.8M
      invalid = 0;
759
760
12.8M
      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
12.8M
      if (i > 0 && empty_qualifier_sequence_p (qualifiers))
770
71.2k
  break;
771
772
44.3M
      for (j = 0; j < num_opnds && j <= stop_at; ++j, ++qualifiers)
773
31.5M
  if (inst->operands[j].qualifier != *qualifiers
774
21.4M
       && inst->operands[j].qualifier != AARCH64_OPND_QLF_UNKNOWN)
775
5.00M
    invalid += 1;
776
777
12.7M
      if (min_invalid > invalid)
778
11.2M
  min_invalid = invalid;
779
780
      /* Qualifiers established.  */
781
12.7M
      if (min_invalid == 0)
782
9.22M
  break;
783
12.7M
    }
784
785
9.29M
  *invalid_count = min_invalid;
786
9.29M
  if (min_invalid == 0)
787
9.22M
    {
788
      /* Fill the result in *RET.  */
789
9.22M
      int j;
790
9.22M
      qualifiers = *qualifiers_list;
791
792
9.22M
      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.0M
      for (j = 0; j <= stop_at; ++j, ++qualifiers)
799
21.8M
  ret[j] = *qualifiers;
800
51.9M
      for (; j < AARCH64_MAX_OPND_NUM; ++j)
801
42.6M
  ret[j] = AARCH64_OPND_QLF_UNKNOWN;
802
803
9.22M
      DEBUG_TRACE ("SUCCESS");
804
9.22M
      return 1;
805
9.22M
    }
806
807
71.2k
  DEBUG_TRACE ("FAIL");
808
71.2k
  return 0;
809
9.29M
}
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.12M
{
826
8.12M
  int i;
827
8.12M
  aarch64_opnd_qualifier_seq_t qualifiers;
828
829
8.12M
  if (!aarch64_find_best_match (inst, inst->opcode->qualifiers_list, -1,
830
8.12M
        qualifiers, invalid_count))
831
43.6k
    {
832
43.6k
      DEBUG_TRACE ("matching FAIL");
833
43.6k
      return 0;
834
43.6k
    }
835
836
  /* Update the qualifiers.  */
837
8.07M
  if (update_p)
838
26.9M
    for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
839
26.9M
      {
840
26.9M
  if (inst->opcode->operands[i] == AARCH64_OPND_NIL)
841
8.07M
    break;
842
18.8M
  DEBUG_TRACE_IF (inst->operands[i].qualifier != qualifiers[i],
843
18.8M
      "update %s with %s for operand %d",
844
18.8M
      aarch64_get_qualifier_name (inst->operands[i].qualifier),
845
18.8M
      aarch64_get_qualifier_name (qualifiers[i]), i);
846
18.8M
  inst->operands[i].qualifier = qualifiers[i];
847
18.8M
      }
848
849
8.07M
  DEBUG_TRACE ("matching SUCCESS");
850
8.07M
  return 1;
851
8.12M
}
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.5k
{
863
97.5k
  int amount;
864
865
97.5k
  DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 ")", value, value);
866
867
97.5k
  if (is32)
868
16.9k
    {
869
      /* Allow all zeros or all ones in top 32-bits, so that
870
   32-bit constant expressions like ~0x80000000 are
871
   permitted.  */
872
16.9k
      if (value >> 32 != 0 && value >> 32 != 0xffffffff)
873
  /* Immediate out of range.  */
874
0
  return false;
875
16.9k
      value &= 0xffffffff;
876
16.9k
    }
877
878
  /* first, try movz then movn */
879
97.5k
  amount = -1;
880
97.5k
  if ((value & ((uint64_t) 0xffff << 0)) == value)
881
23.4k
    amount = 0;
882
74.0k
  else if ((value & ((uint64_t) 0xffff << 16)) == value)
883
12.0k
    amount = 16;
884
61.9k
  else if (!is32 && (value & ((uint64_t) 0xffff << 32)) == value)
885
25.4k
    amount = 32;
886
36.5k
  else if (!is32 && (value & ((uint64_t) 0xffff << 48)) == value)
887
5.29k
    amount = 48;
888
889
97.5k
  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
66.2k
  if (shift_amount != NULL)
896
0
    *shift_amount = amount;
897
898
66.2k
  DEBUG_TRACE ("exit true with amount %d", amount);
899
900
66.2k
  return true;
901
97.5k
}
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
346k
#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.08M
{
935
4.08M
  const simd_imm_encoding *imm1 = (const simd_imm_encoding *)i1;
936
4.08M
  const simd_imm_encoding *imm2 = (const simd_imm_encoding *)i2;
937
938
4.08M
  if (imm1->imm < imm2->imm)
939
2.04M
    return -1;
940
2.03M
  if (imm1->imm > imm2->imm)
941
1.69M
    return +1;
942
346k
  return 0;
943
2.03M
}
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
346k
{
1036
346k
  simd_imm_encoding imm_enc;
1037
346k
  const simd_imm_encoding *imm_encoding;
1038
346k
  static bool initialized = false;
1039
346k
  uint64_t upper;
1040
346k
  int i;
1041
1042
346k
  DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 "), esize: %d", value,
1043
346k
         value, esize);
1044
1045
346k
  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
346k
  upper = (uint64_t) -1 << (esize * 4) << (esize * 4);
1054
346k
  if ((value & ~upper) != value && (value | upper) != value)
1055
0
    return false;
1056
1057
  /* Replicate to a full 64-bit value.  */
1058
346k
  value &= ~upper;
1059
597k
  for (i = esize * 8; i < 64; i *= 2)
1060
250k
    value |= (value << i);
1061
1062
346k
  imm_enc.imm = value;
1063
346k
  imm_encoding = (const simd_imm_encoding *)
1064
346k
    bsearch(&imm_enc, simd_immediates, TOTAL_IMM_NB,
1065
346k
            sizeof(simd_immediates[0]), simd_imm_encoding_cmp);
1066
346k
  if (imm_encoding == NULL)
1067
0
    {
1068
0
      DEBUG_TRACE ("exit with false");
1069
0
      return false;
1070
0
    }
1071
346k
  if (encoding != NULL)
1072
0
    *encoding = imm_encoding->encoding;
1073
346k
  DEBUG_TRACE ("exit with true");
1074
346k
  return true;
1075
346k
}
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
674
{
1084
674
  int i, ret;
1085
674
  uint32_t byte;
1086
1087
674
  ret = 0;
1088
6.06k
  for (i = 0; i < 8; i++)
1089
5.39k
    {
1090
5.39k
      byte = (imm >> (8 * i)) & 0xff;
1091
5.39k
      if (byte == 0xff)
1092
2.86k
  ret |= 1 << i;
1093
2.52k
      else if (byte != 0x00)
1094
0
  return -1;
1095
5.39k
    }
1096
674
  return ret;
1097
674
}
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.17k
{
1117
3.17k
  if (mismatch_detail == NULL)
1118
3.17k
    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.3k
{
1150
49.3k
  if (mismatch_detail == NULL)
1151
49.3k
    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
642
{
1180
642
  if (mismatch_detail == NULL)
1181
642
    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
96.1k
{
1190
96.1k
  if (mismatch_detail == NULL)
1191
96.1k
    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
759
{
1222
759
  if (mismatch_detail == NULL)
1223
759
    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.4k
{
1252
44.4k
  if (mismatch_detail == NULL)
1253
44.4k
    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
92.8k
{
1267
92.8k
  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
92.8k
  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
92.8k
  return true;
1280
92.8k
}
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
395k
{
1290
395k
  if (opnd->reglist.num_regs != num_regs)
1291
759
    {
1292
759
      set_reg_list_length_error (mismatch_detail, idx, num_regs);
1293
759
      return false;
1294
759
    }
1295
394k
  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
394k
  return true;
1301
394k
}
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.35M
{
1335
1.35M
  const aarch64_operand *operand = get_operand_from_code (type);
1336
1.35M
  uint8_t size = get_operand_fields_width (operand);
1337
1.35M
  bool unsigned_imm = operand_need_unsigned_offset (operand);
1338
1.35M
  bool (*value_fit_field) (int64_t, unsigned)
1339
1.35M
    = (unsigned_imm
1340
1.35M
      ? value_fit_unsigned_field_p
1341
1.35M
      : value_fit_signed_field_p);
1342
1343
1.35M
  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.35M
  return true;
1350
1.35M
}
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
203k
{
1370
203k
  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
203k
  int max_index = max_value * range_size;
1386
203k
  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
203k
  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
203k
  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
203k
  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
203k
  return true;
1428
203k
}
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.6k
{
1436
18.6k
  unsigned num_bytes = 0; /* total number of bytes transferred.  */
1437
18.6k
  enum aarch64_operand_class opnd_class;
1438
18.6k
  enum aarch64_opnd type;
1439
1440
55.2k
  for (int i = 0; i < AARCH64_MAX_OPND_NUM; i++)
1441
55.2k
    {
1442
55.2k
      type = opnds[i].type;
1443
55.2k
      opnd_class = aarch64_operands[type].op_class;
1444
55.2k
      if (opnd_class == AARCH64_OPND_CLASS_ADDRESS)
1445
18.6k
  break;
1446
36.5k
      num_bytes += aarch64_get_qualifier_esize (opnds[i].qualifier);
1447
36.5k
    }
1448
18.6k
  return num_bytes;
1449
18.6k
}
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
18.8M
{
1474
18.8M
  unsigned num, modifiers, shift;
1475
18.8M
  unsigned char size;
1476
18.8M
  int64_t imm, min_value, max_value;
1477
18.8M
  uint64_t uvalue, mask;
1478
18.8M
  const aarch64_opnd_info *opnd = opnds + idx;
1479
18.8M
  aarch64_opnd_qualifier_t qualifier = opnd->qualifier;
1480
18.8M
  int i;
1481
1482
18.8M
  assert (opcode->operands[idx] == opnd->type && opnd->type == type);
1483
1484
18.8M
  switch (aarch64_operands[type].op_class)
1485
18.8M
    {
1486
6.14M
    case AARCH64_OPND_CLASS_INT_REG:
1487
      /* Check for pair of xzr registers.  */
1488
6.14M
      if (type == AARCH64_OPND_PAIRREG_OR_XZR
1489
4.01k
    && opnds[idx - 1].reg.regno == 0x1f)
1490
1.78k
  {
1491
1.78k
    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.78k
  }
1499
      /* Check pair reg constraints for instructions taking a pair of
1500
   consecutively-numbered general-purpose registers.  */
1501
6.13M
      else if (type == AARCH64_OPND_PAIRREG
1502
6.13M
         || type == AARCH64_OPND_PAIRREG_OR_XZR)
1503
9.39k
  {
1504
9.39k
    assert (idx == 1 || idx == 2 || idx == 3 || idx == 5);
1505
9.39k
    if (opnds[idx - 1].reg.regno % 2 != 0)
1506
3.17k
      {
1507
3.17k
        set_syntax_error (mismatch_detail, idx - 1,
1508
3.17k
        _("reg pair must start from even reg"));
1509
3.17k
        return false;
1510
3.17k
      }
1511
6.22k
    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.22k
    break;
1518
6.22k
  }
1519
1520
      /* <Xt> may be optional in some IC and TLBI instructions.  */
1521
6.13M
      if (type == AARCH64_OPND_Rt_SYS)
1522
1.04k
  {
1523
1.04k
    assert (idx == 1 && (aarch64_get_operand_class (opnds[0].type)
1524
1.04k
             == AARCH64_OPND_CLASS_SYSTEM));
1525
1.04k
    if (!(opnds[1].present && aarch64_sys_ins_reg_tlbid_xt (opnds[0].sysins_op)))
1526
997
      {
1527
997
        if (opnds[1].present
1528
982
      && !aarch64_sys_ins_reg_has_xt (opnds[0].sysins_op))
1529
637
    {
1530
637
      set_other_error (mismatch_detail, idx, _("extraneous register"));
1531
637
      return false;
1532
637
    }
1533
360
        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
360
     }
1540
1.04k
  }
1541
6.13M
      break;
1542
1543
6.13M
    case AARCH64_OPND_CLASS_SVE_REG:
1544
1.68M
      switch (type)
1545
1.68M
  {
1546
4.96k
  case AARCH64_OPND_SVE_Zm3_INDEX:
1547
15.0k
  case AARCH64_OPND_SVE_Zm3_22_INDEX:
1548
15.6k
  case AARCH64_OPND_SVE_Zm3_19_INDEX:
1549
21.9k
  case AARCH64_OPND_SVE_Zm3_11_INDEX:
1550
25.4k
  case AARCH64_OPND_SVE_Zm3_10_INDEX:
1551
29.1k
  case AARCH64_OPND_SVE_Zm4_11_INDEX:
1552
34.8k
  case AARCH64_OPND_SVE_Zm4_INDEX:
1553
34.8k
    size = get_operand_fields_width (get_operand_from_code (type));
1554
34.8k
    shift = get_operand_specific_data (&aarch64_operands[type]);
1555
34.8k
    if (!check_reglane (opnd, mismatch_detail, idx,
1556
34.8k
            "z", 0, (1 << shift) - 1,
1557
34.8k
            0, (1u << (size - shift)) - 1))
1558
0
      return false;
1559
34.8k
    break;
1560
1561
34.8k
  case AARCH64_OPND_SVE_Zm1_23_INDEX:
1562
457
    size = get_operand_fields_width (get_operand_from_code (type));
1563
457
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31, 0, 1))
1564
0
      return 0;
1565
457
    break;
1566
1567
457
  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.84k
  case AARCH64_OPND_SVE_Zn_INDEX:
1575
2.84k
    size = aarch64_get_qualifier_esize (opnd->qualifier);
1576
2.84k
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31,
1577
2.84k
            0, 64 / size - 1))
1578
0
      return false;
1579
2.84k
    break;
1580
1581
2.84k
  case AARCH64_OPND_SVE_Zn_5_INDEX:
1582
446
    size = aarch64_get_qualifier_esize (opnd->qualifier);
1583
446
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31,
1584
446
            0, 16 / size - 1))
1585
0
      return false;
1586
446
    break;
1587
1588
446
  case AARCH64_OPND_SME_PNn3_INDEX1:
1589
180
  case AARCH64_OPND_SME_PNn3_INDEX2:
1590
180
    size = get_operand_field_width (get_operand_from_code (type), 0);
1591
180
    if (!check_reglane (opnd, mismatch_detail, idx, "pn", 8, 15,
1592
180
            0, (1 << size) - 1))
1593
0
      return false;
1594
180
    break;
1595
1596
1.01k
  case AARCH64_OPND_SVE_Zm3_12_INDEX:
1597
1.32k
  case AARCH64_OPND_SME_Zn_INDEX1_16:
1598
1.57k
  case AARCH64_OPND_SME_Zn_INDEX2_15:
1599
2.23k
  case AARCH64_OPND_SME_Zn_INDEX2_16:
1600
2.37k
  case AARCH64_OPND_SME_Zn_INDEX3_14:
1601
2.58k
  case AARCH64_OPND_SME_Zn_INDEX3_15:
1602
2.75k
  case AARCH64_OPND_SME_Zn_INDEX4_14:
1603
2.83k
  case AARCH64_OPND_SVE_Zn0_INDEX:
1604
2.92k
  case AARCH64_OPND_SVE_Zn1_17_INDEX:
1605
2.98k
  case AARCH64_OPND_SVE_Zn2_18_INDEX:
1606
3.21k
  case AARCH64_OPND_SVE_Zn3_22_INDEX:
1607
3.29k
  case AARCH64_OPND_SVE_Zd0_INDEX:
1608
3.39k
  case AARCH64_OPND_SVE_Zd1_17_INDEX:
1609
3.47k
  case AARCH64_OPND_SVE_Zd2_18_INDEX:
1610
3.61k
  case AARCH64_OPND_SVE_Zd3_22_INDEX:
1611
3.61k
    size = get_operand_fields_width (get_operand_from_code (type)) - 5;
1612
3.61k
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31,
1613
3.61k
            0, (1 << size) - 1))
1614
0
      return false;
1615
3.61k
    break;
1616
1617
3.61k
  case AARCH64_OPND_SME_Zm_INDEX1:
1618
3.18k
  case AARCH64_OPND_SME_Zm_INDEX2:
1619
3.61k
  case AARCH64_OPND_SME_Zm_INDEX2_3:
1620
5.52k
  case AARCH64_OPND_SME_Zm_INDEX3_1:
1621
8.26k
  case AARCH64_OPND_SME_Zm_INDEX3_2:
1622
9.04k
  case AARCH64_OPND_SME_Zm_INDEX3_3:
1623
13.9k
  case AARCH64_OPND_SME_Zm_INDEX3_10:
1624
15.9k
  case AARCH64_OPND_SME_Zm_INDEX4_1:
1625
17.0k
  case AARCH64_OPND_SME_Zm_INDEX4_2:
1626
33.5k
  case AARCH64_OPND_SME_Zm_INDEX4_3:
1627
39.9k
  case AARCH64_OPND_SME_Zm_INDEX4_10:
1628
39.9k
    size = get_operand_fields_width (get_operand_from_code (type)) - 5;
1629
39.9k
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 15,
1630
39.9k
            0, (1 << size) - 1))
1631
0
      return false;
1632
39.9k
    break;
1633
1634
39.9k
  case AARCH64_OPND_SME_Zk_INDEX:
1635
4.90k
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31, 0, 3))
1636
0
      return false;
1637
4.90k
    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
4.90k
    break;
1644
1645
8.35k
  case AARCH64_OPND_SME_Zm:
1646
8.38k
  case AARCH64_OPND_SME_Zm_17:
1647
8.38k
    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.38k
    break;
1653
1654
10.0k
  case AARCH64_OPND_SME_Zn_6_3:
1655
10.0k
    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.0k
    break;
1662
1663
10.0k
  case AARCH64_OPND_SME_Zm_17_3:
1664
9.67k
    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.67k
    break;
1671
1672
10.1k
  case AARCH64_OPND_SME_PnT_Wm_imm:
1673
10.1k
    size = aarch64_get_qualifier_esize (opnd->qualifier);
1674
10.1k
    max_value = 16 / size - 1;
1675
10.1k
    if (!check_za_access (opnd, mismatch_detail, idx,
1676
10.1k
        12, max_value, 1, 0, get_opcode_dependent_value (opcode)))
1677
0
      return false;
1678
10.1k
    break;
1679
1680
1.55M
  default:
1681
1.55M
    break;
1682
1.68M
  }
1683
1.68M
      break;
1684
1685
1.68M
    case AARCH64_OPND_CLASS_SVE_REGLIST:
1686
358k
      switch (type)
1687
358k
  {
1688
886
  case AARCH64_OPND_SME_Pdx2:
1689
23.9k
  case AARCH64_OPND_SME_Zdnx2:
1690
31.9k
  case AARCH64_OPND_SME_Zdnx4:
1691
32.3k
  case AARCH64_OPND_SME_Znx2_6_3:
1692
33.0k
  case AARCH64_OPND_SME_Zmx2_17_3:
1693
35.7k
  case AARCH64_OPND_SME_Zmx2:
1694
36.1k
  case AARCH64_OPND_SME_Zmx4:
1695
53.9k
  case AARCH64_OPND_SME_Znx2:
1696
53.9k
  case AARCH64_OPND_SME_Znx2_BIT_INDEX:
1697
59.9k
  case AARCH64_OPND_SME_Znx4:
1698
59.9k
    num = get_operand_specific_data (&aarch64_operands[type]);
1699
59.9k
    if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
1700
0
      return false;
1701
59.9k
    if (((opnd->reglist.first_regno % num) != 0)
1702
59.9k
        || (type == AARCH64_OPND_SME_Znx2_6_3
1703
337
      && opnd->reglist.first_regno > 15)
1704
59.9k
        || (type == AARCH64_OPND_SME_Zmx2_17_3
1705
710
      && 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
59.9k
    break;
1712
1713
59.9k
  case AARCH64_OPND_SME_Ztx2_STRIDED:
1714
13.0k
  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.0k
    num = get_operand_specific_data (&aarch64_operands[type]);
1718
13.0k
    if (!check_reglist (opnd, mismatch_detail, idx, num, 16 / num))
1719
0
      return false;
1720
13.0k
    num = 16 | (opnd->reglist.stride - 1);
1721
13.0k
    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.0k
    break;
1728
1729
13.0k
  case AARCH64_OPND_SME_PdxN:
1730
12.6k
  case AARCH64_OPND_SVE_ZnxN:
1731
285k
  case AARCH64_OPND_SVE_ZtxN:
1732
285k
    num = get_opcode_dependent_value (opcode);
1733
285k
    if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
1734
0
      return false;
1735
285k
    break;
1736
1737
285k
  case AARCH64_OPND_SME_Zmx2_INDEX_22:
1738
318
    num = get_operand_specific_data (&aarch64_operands[type]);
1739
318
    if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
1740
0
        return false;
1741
318
    break;
1742
1743
318
  case AARCH64_OPND_SME_Zn7xN_UNTYPED:
1744
124
    num = get_opcode_dependent_value (opcode);
1745
124
    if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
1746
0
        return false;
1747
124
    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
124
    break;
1753
1754
124
  default:
1755
0
    abort ();
1756
358k
  }
1757
358k
      break;
1758
1759
358k
    case AARCH64_OPND_CLASS_ZA_ACCESS:
1760
193k
      switch (type)
1761
193k
  {
1762
1.44k
  case AARCH64_OPND_SME_ZA_HV_idx_src:
1763
85.4k
  case AARCH64_OPND_SME_ZA_HV_idx_dest:
1764
131k
  case AARCH64_OPND_SME_ZA_HV_idx_ldstr:
1765
131k
    size = aarch64_get_qualifier_esize (opnd->qualifier);
1766
131k
    max_value = 16 / size - 1;
1767
131k
    if (!check_za_access (opnd, mismatch_detail, idx, 12, max_value, 1,
1768
131k
        get_opcode_dependent_value (opcode),
1769
131k
        get_opcode_dependent_vg_status (opcode)))
1770
0
      return false;
1771
131k
    break;
1772
1773
131k
  case AARCH64_OPND_SME_ZA_array_off4:
1774
974
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 15, 1,
1775
974
        get_opcode_dependent_value (opcode),
1776
974
        get_opcode_dependent_vg_status (opcode)))
1777
0
      return false;
1778
974
    break;
1779
1780
10.5k
  case AARCH64_OPND_SME_ZA_array_off3_0:
1781
11.1k
  case AARCH64_OPND_SME_ZA_array_off3_5:
1782
11.1k
    if (!check_za_access (opnd, mismatch_detail, idx, 8, 7, 1,
1783
11.1k
        get_opcode_dependent_value (opcode),
1784
11.1k
        get_opcode_dependent_vg_status (opcode)))
1785
0
      return false;
1786
11.1k
    break;
1787
1788
11.1k
  case AARCH64_OPND_SME_ZA_array_off1x4:
1789
6.31k
    if (!check_za_access (opnd, mismatch_detail, idx, 8, 1, 4,
1790
6.31k
        get_opcode_dependent_value (opcode),
1791
6.31k
        get_opcode_dependent_vg_status (opcode)))
1792
0
      return false;
1793
6.31k
    break;
1794
1795
6.31k
  case AARCH64_OPND_SME_ZA_array_off2x2:
1796
5.72k
    if (!check_za_access (opnd, mismatch_detail, idx, 8, 3, 2,
1797
5.72k
        get_opcode_dependent_value (opcode),
1798
5.72k
        get_opcode_dependent_vg_status (opcode)))
1799
0
      return false;
1800
5.72k
    break;
1801
1802
7.63k
  case AARCH64_OPND_SME_ZA_array_off2x4:
1803
7.63k
    if (!check_za_access (opnd, mismatch_detail, idx, 8, 3, 4,
1804
7.63k
        get_opcode_dependent_value (opcode),
1805
7.63k
        get_opcode_dependent_vg_status (opcode)))
1806
0
      return false;
1807
7.63k
    break;
1808
1809
21.4k
  case AARCH64_OPND_SME_ZA_array_off3x2:
1810
21.4k
    if (!check_za_access (opnd, mismatch_detail, idx, 8, 7, 2,
1811
21.4k
        get_opcode_dependent_value (opcode),
1812
21.4k
        get_opcode_dependent_vg_status (opcode)))
1813
0
      return false;
1814
21.4k
    break;
1815
1816
21.4k
  case AARCH64_OPND_SME_ZA_array_vrsb_1:
1817
115
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 7, 2,
1818
115
        get_opcode_dependent_value (opcode),
1819
115
        get_opcode_dependent_vg_status (opcode)))
1820
0
      return false;
1821
115
    break;
1822
1823
115
  case AARCH64_OPND_SME_ZA_array_vrsh_1:
1824
28
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 3, 2,
1825
28
        get_opcode_dependent_value (opcode),
1826
28
        get_opcode_dependent_vg_status (opcode)))
1827
0
      return false;
1828
28
    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
267
  case AARCH64_OPND_SME_ZA_array_vrsd_1:
1838
267
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 0, 2,
1839
267
        get_opcode_dependent_value (opcode),
1840
267
        get_opcode_dependent_vg_status (opcode)))
1841
0
      return false;
1842
267
    break;
1843
1844
301
  case AARCH64_OPND_SME_ZA_array_vrsb_2:
1845
301
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 3, 4,
1846
301
        get_opcode_dependent_value (opcode),
1847
301
        get_opcode_dependent_vg_status (opcode)))
1848
0
      return false;
1849
301
    break;
1850
1851
301
  case AARCH64_OPND_SME_ZA_array_vrsh_2:
1852
124
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 1, 4,
1853
124
        get_opcode_dependent_value (opcode),
1854
124
        get_opcode_dependent_vg_status (opcode)))
1855
0
      return false;
1856
124
    break;
1857
1858
734
  case AARCH64_OPND_SME_ZA_ARRAY4:
1859
734
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 15, 1,
1860
734
        get_opcode_dependent_value (opcode),
1861
734
        get_opcode_dependent_vg_status (opcode)))
1862
0
      return false;
1863
734
    break;
1864
1865
734
  case AARCH64_OPND_SME_ZA_array_vrss_2:
1866
602
  case AARCH64_OPND_SME_ZA_array_vrsd_2:
1867
602
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 0, 4,
1868
602
        get_opcode_dependent_value (opcode),
1869
602
        get_opcode_dependent_vg_status (opcode)))
1870
0
      return false;
1871
602
    break;
1872
1873
5.45k
  case AARCH64_OPND_SME_ZA_HV_idx_srcxN:
1874
7.24k
  case AARCH64_OPND_SME_ZA_HV_idx_destxN:
1875
7.24k
    size = aarch64_get_qualifier_esize (opnd->qualifier);
1876
7.24k
    num = get_opcode_dependent_value (opcode);
1877
7.24k
    max_value = 16 / num / size;
1878
7.24k
    if (max_value > 0)
1879
7.08k
      max_value -= 1;
1880
7.24k
    if (!check_za_access (opnd, mismatch_detail, idx, 12, max_value, num,
1881
7.24k
        0, get_opcode_dependent_value (opcode)))
1882
0
      return false;
1883
7.24k
    break;
1884
1885
7.24k
  default:
1886
0
    abort ();
1887
193k
  }
1888
193k
      break;
1889
1890
1.06M
    case AARCH64_OPND_CLASS_PRED_REG:
1891
1.06M
      switch (type)
1892
1.06M
  {
1893
2.71k
  case AARCH64_OPND_SME_PNd3:
1894
34.4k
  case AARCH64_OPND_SME_PNg3:
1895
34.4k
    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.4k
    break;
1901
1902
1.02M
  default:
1903
1.02M
    if (opnd->reg.regno >= 8
1904
74.2k
        && 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.02M
    break;
1910
1.06M
  }
1911
1.06M
      break;
1912
1913
1.06M
    case AARCH64_OPND_CLASS_COND:
1914
25.7k
      if (type == AARCH64_OPND_COND1
1915
591
    && (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
25.7k
      break;
1921
1922
3.25M
    case AARCH64_OPND_CLASS_ADDRESS:
1923
      /* Check writeback.  */
1924
3.25M
      switch (opcode->iclass)
1925
3.25M
  {
1926
245k
  case ldst_pos:
1927
327k
  case ldst_unscaled:
1928
473k
  case ldstnapair_offs:
1929
656k
  case ldstpair_off:
1930
669k
  case ldst_unpriv:
1931
669k
    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
669k
    break;
1938
669k
  case ldst_imm10:
1939
10.2k
    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.2k
    break;
1946
52.1k
  case ldst_imm9:
1947
304k
  case ldstpair_indexed:
1948
311k
  case asisdlsep:
1949
325k
  case asisdlsop:
1950
325k
    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
325k
    break;
1957
325k
  case rcpc3:
1958
24.2k
    if (opnd->addr.writeback)
1959
1.73k
      if ((type == AARCH64_OPND_RCPC3_ADDR_PREIND_WB
1960
287
     && !opnd->addr.preind)
1961
1.73k
    || (type == AARCH64_OPND_RCPC3_ADDR_POSTIND
1962
70
        && !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.2k
    break;
1970
2.22M
  default:
1971
2.22M
    assert (opnd->addr.writeback == 0);
1972
2.22M
    break;
1973
3.25M
  }
1974
3.25M
      switch (type)
1975
3.25M
  {
1976
554k
  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
554k
    size = aarch64_get_qualifier_esize (opnd->qualifier);
1982
554k
    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
554k
    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
554k
    break;
1994
554k
  case AARCH64_OPND_ADDR_OFFSET:
1995
139k
  case AARCH64_OPND_ADDR_SIMM9:
1996
    /* Unscaled signed 9 bits immediate offset.  */
1997
139k
    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
139k
    break;
2003
2004
139k
  case AARCH64_OPND_ADDR_SIMM10:
2005
    /* Scaled signed 10 bits immediate offset.  */
2006
10.2k
    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.2k
    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.2k
    break;
2017
2018
25.6k
  case AARCH64_OPND_ADDR_SIMM11:
2019
    /* Signed 11 bits immediate offset (multiple of 16).  */
2020
25.6k
    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
25.6k
    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
25.6k
    break;
2032
2033
25.6k
  case AARCH64_OPND_ADDR_SIMM13:
2034
    /* Signed 13 bits immediate offset (multiple of 16).  */
2035
9.07k
    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.07k
    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.07k
    break;
2047
2048
20.5k
  case AARCH64_OPND_SIMD_ADDR_POST:
2049
    /* AdvSIMD load/store multiple structures, post-index.  */
2050
20.5k
    assert (idx == 1);
2051
20.5k
    if (opnd->addr.offset.is_reg)
2052
17.3k
      {
2053
17.3k
        if (value_in_range_p (opnd->addr.offset.regno, 0, 30))
2054
17.3k
    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.3k
      }
2062
3.20k
    else
2063
3.20k
      {
2064
3.20k
        const aarch64_opnd_info *prev = &opnds[idx-1];
2065
3.20k
        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.20k
        int is_ld1r = get_opcode_dependent_value (opcode) == 1;
2069
3.20k
        if (opcode->operands[0] == AARCH64_OPND_LVt_AL)
2070
    /* Special handling of loading single structure to all lane.  */
2071
667
    num_bytes = (is_ld1r ? 1 : prev->reglist.num_regs)
2072
667
      * aarch64_get_qualifier_esize (prev->qualifier);
2073
2.53k
        else
2074
2.53k
    num_bytes = prev->reglist.num_regs
2075
2.53k
      * aarch64_get_qualifier_esize (prev->qualifier)
2076
2.53k
      * aarch64_get_qualifier_nelem (prev->qualifier);
2077
3.20k
        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.20k
      }
2084
3.20k
    break;
2085
2086
61.7k
  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
61.7k
    size = aarch64_get_qualifier_esize (opnd->qualifier);
2091
    /* It is either no shift or shift by the binary logarithm of SIZE.  */
2092
61.7k
    if (opnd->shifter.amount != 0
2093
34.3k
        && 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
61.7k
    switch (opnd->shifter.kind)
2102
61.7k
      {
2103
2.02k
      case AARCH64_MOD_UXTW:
2104
18.9k
      case AARCH64_MOD_LSL:
2105
21.4k
      case AARCH64_MOD_SXTW:
2106
26.1k
      case AARCH64_MOD_SXTX: break;
2107
35.6k
      default:
2108
35.6k
        set_other_error (mismatch_detail, idx,
2109
35.6k
             _("invalid extend/shift operator"));
2110
35.6k
        return false;
2111
61.7k
      }
2112
26.1k
    break;
2113
2114
245k
  case AARCH64_OPND_ADDR_UIMM12:
2115
245k
    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
245k
    size = aarch64_get_qualifier_esize (qualifier);
2120
245k
    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
245k
    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
245k
    break;
2132
2133
245k
  case AARCH64_OPND_ADDR_PCREL9:
2134
288k
  case AARCH64_OPND_ADDR_PCREL14:
2135
734k
  case AARCH64_OPND_ADDR_PCREL19:
2136
1.08M
  case AARCH64_OPND_ADDR_PCREL21:
2137
1.35M
  case AARCH64_OPND_ADDR_PCREL26:
2138
1.35M
    {
2139
1.35M
      imm = opnd->imm.value;
2140
1.35M
      if (operand_need_shift_by_two (get_operand_from_code (type)))
2141
1.00M
        {
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.00M
    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.00M
    imm >>= 2;
2152
1.00M
        }
2153
2154
1.35M
      if (!check_immediate_out_of_range (imm, type, mismatch_detail, idx))
2155
0
        return false;
2156
1.35M
    }
2157
1.35M
    break;
2158
2159
1.35M
  case AARCH64_OPND_SME_ADDR_RI_U4xVL:
2160
974
    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
974
    break;
2166
2167
63.1k
  case AARCH64_OPND_SVE_ADDR_RI_S4xVL:
2168
75.3k
  case AARCH64_OPND_SVE_ADDR_RI_S4x2xVL:
2169
78.7k
  case AARCH64_OPND_SVE_ADDR_RI_S4x3xVL:
2170
85.7k
  case AARCH64_OPND_SVE_ADDR_RI_S4x4xVL:
2171
85.7k
    min_value = -8;
2172
85.7k
    max_value = 7;
2173
94.9k
  sve_imm_offset_vl:
2174
94.9k
    assert (!opnd->addr.offset.is_reg);
2175
94.9k
    assert (opnd->addr.preind);
2176
94.9k
    num = 1 + get_operand_specific_data (&aarch64_operands[type]);
2177
94.9k
    min_value *= num;
2178
94.9k
    max_value *= num;
2179
94.9k
    if ((opnd->addr.offset.imm != 0 && !opnd->shifter.operator_present)
2180
94.9k
        || (opnd->shifter.operator_present
2181
88.6k
      && 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
94.9k
    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
94.9k
    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
94.9k
    break;
2199
2200
94.9k
  case AARCH64_OPND_SVE_ADDR_RI_S6xVL:
2201
3.27k
    min_value = -32;
2202
3.27k
    max_value = 31;
2203
3.27k
    goto sve_imm_offset_vl;
2204
2205
5.87k
  case AARCH64_OPND_SVE_ADDR_RI_S9xVL:
2206
5.87k
    min_value = -256;
2207
5.87k
    max_value = 255;
2208
5.87k
    goto sve_imm_offset_vl;
2209
2210
6.26k
  case AARCH64_OPND_SVE_ADDR_RI_U6:
2211
11.1k
  case AARCH64_OPND_SVE_ADDR_RI_U6x2:
2212
12.8k
  case AARCH64_OPND_SVE_ADDR_RI_U6x4:
2213
14.5k
  case AARCH64_OPND_SVE_ADDR_RI_U6x8:
2214
14.5k
    min_value = 0;
2215
14.5k
    max_value = 63;
2216
33.3k
  sve_imm_offset:
2217
33.3k
    assert (!opnd->addr.offset.is_reg);
2218
33.3k
    assert (opnd->addr.preind);
2219
33.3k
    num = 1 << get_operand_specific_data (&aarch64_operands[type]);
2220
33.3k
    min_value *= num;
2221
33.3k
    max_value *= num;
2222
33.3k
    if (opnd->shifter.operator_present
2223
33.3k
        || 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
33.3k
    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
33.3k
    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
33.3k
    break;
2241
2242
33.3k
  case AARCH64_OPND_SVE_ADDR_RI_S4x16:
2243
2.96k
  case AARCH64_OPND_SVE_ADDR_RI_S4x32:
2244
2.96k
    min_value = -8;
2245
2.96k
    max_value = 7;
2246
2.96k
    goto sve_imm_offset;
2247
2248
15.9k
  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
15.9k
    assert (opnd->addr.offset.is_reg);
2253
15.9k
    assert (opnd->addr.preind);
2254
15.9k
    assert ((aarch64_operands[type].flags & OPD_F_NO_ZR) == 0);
2255
15.9k
    assert (opnd->shifter.kind == AARCH64_MOD_LSL);
2256
15.9k
    assert (opnd->shifter.operator_present == 0);
2257
15.9k
    break;
2258
2259
15.9k
  case AARCH64_OPND_SVE_ADDR_RR:
2260
19.9k
  case AARCH64_OPND_SVE_ADDR_RR_LSL1:
2261
24.7k
  case AARCH64_OPND_SVE_ADDR_RR_LSL2:
2262
40.9k
  case AARCH64_OPND_SVE_ADDR_RR_LSL3:
2263
56.5k
  case AARCH64_OPND_SVE_ADDR_RR_LSL4:
2264
66.1k
  case AARCH64_OPND_SVE_ADDR_RM:
2265
70.6k
  case AARCH64_OPND_SVE_ADDR_RM_LSL1:
2266
75.2k
  case AARCH64_OPND_SVE_ADDR_RM_LSL2:
2267
78.8k
  case AARCH64_OPND_SVE_ADDR_RM_LSL3:
2268
78.8k
  case AARCH64_OPND_SVE_ADDR_RM_LSL4:
2269
96.1k
  case AARCH64_OPND_SVE_ADDR_RX:
2270
106k
  case AARCH64_OPND_SVE_ADDR_RX_LSL1:
2271
117k
  case AARCH64_OPND_SVE_ADDR_RX_LSL2:
2272
122k
  case AARCH64_OPND_SVE_ADDR_RX_LSL3:
2273
126k
  case AARCH64_OPND_SVE_ADDR_RX_LSL4:
2274
149k
  case AARCH64_OPND_SVE_ADDR_RZ:
2275
152k
  case AARCH64_OPND_SVE_ADDR_RZ_LSL1:
2276
154k
  case AARCH64_OPND_SVE_ADDR_RZ_LSL2:
2277
158k
  case AARCH64_OPND_SVE_ADDR_RZ_LSL3:
2278
158k
    modifiers = 1 << AARCH64_MOD_LSL;
2279
231k
  sve_rr_operand:
2280
231k
    assert (opnd->addr.offset.is_reg);
2281
231k
    assert (opnd->addr.preind);
2282
231k
    if ((aarch64_operands[type].flags & OPD_F_NO_ZR) != 0
2283
47.9k
        && 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
231k
    if (((1 << opnd->shifter.kind) & modifiers) == 0
2290
231k
        || (opnd->shifter.amount
2291
231k
      != 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
231k
    break;
2298
2299
231k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW_14:
2300
46.7k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW_22:
2301
48.6k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW1_14:
2302
56.9k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW1_22:
2303
58.2k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW2_14:
2304
65.5k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW2_22:
2305
66.0k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW3_14:
2306
73.7k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW3_22:
2307
73.7k
    modifiers = (1 << AARCH64_MOD_SXTW) | (1 << AARCH64_MOD_UXTW);
2308
73.7k
    goto sve_rr_operand;
2309
2310
5.15k
  case AARCH64_OPND_SVE_ADDR_ZI_U5:
2311
11.4k
  case AARCH64_OPND_SVE_ADDR_ZI_U5x2:
2312
14.4k
  case AARCH64_OPND_SVE_ADDR_ZI_U5x4:
2313
15.8k
  case AARCH64_OPND_SVE_ADDR_ZI_U5x8:
2314
15.8k
    min_value = 0;
2315
15.8k
    max_value = 31;
2316
15.8k
    goto sve_imm_offset;
2317
2318
983
  case AARCH64_OPND_SVE_ADDR_ZZ_LSL:
2319
983
    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
297
    modifiers = (1 << AARCH64_MOD_SXTW);
2335
297
    goto sve_zz_operand;
2336
2337
955
  case AARCH64_OPND_SVE_ADDR_ZZ_UXTW:
2338
955
    modifiers = 1 << AARCH64_MOD_UXTW;
2339
955
    goto sve_zz_operand;
2340
2341
15.6k
  case AARCH64_OPND_RCPC3_ADDR_OPT_PREIND_WB:
2342
16.5k
  case AARCH64_OPND_RCPC3_ADDR_OPT_POSTIND:
2343
16.8k
  case AARCH64_OPND_RCPC3_ADDR_PREIND_WB:
2344
16.9k
  case AARCH64_OPND_RCPC3_ADDR_POSTIND:
2345
16.9k
    {
2346
16.9k
      int num_bytes = calc_ldst_datasize (opnds);
2347
16.9k
      int abs_offset = (type == AARCH64_OPND_RCPC3_ADDR_OPT_PREIND_WB
2348
1.25k
            || type == AARCH64_OPND_RCPC3_ADDR_PREIND_WB)
2349
16.9k
        ? opnd->addr.offset.imm * -1
2350
16.9k
        : opnd->addr.offset.imm;
2351
16.9k
      if ((int) num_bytes != abs_offset
2352
15.1k
    && 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
16.9k
    }
2359
16.9k
    break;
2360
2361
16.9k
  case AARCH64_OPND_RCPC3_ADDR_OFFSET:
2362
7.31k
    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
438k
  default:
2369
438k
    break;
2370
3.25M
  }
2371
3.20M
      break;
2372
2373
3.20M
    case AARCH64_OPND_CLASS_SIMD_REGLIST:
2374
58.5k
      if (type == AARCH64_OPND_LEt)
2375
20.4k
  {
2376
    /* Get the upper bound for the element index.  */
2377
20.4k
    num = 16 / aarch64_get_qualifier_esize (qualifier) - 1;
2378
20.4k
    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.4k
  }
2384
      /* The opcode dependent area stores the number of elements in
2385
   each structure to be loaded/stored.  */
2386
58.5k
      num = get_opcode_dependent_value (opcode);
2387
58.5k
      switch (type)
2388
58.5k
  {
2389
4.35k
  case AARCH64_OPND_LVn_LUT:
2390
4.35k
    if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
2391
0
      return 0;
2392
4.35k
    break;
2393
14.9k
  case AARCH64_OPND_LVt:
2394
14.9k
    assert (num >= 1 && num <= 4);
2395
    /* Unless LD1/ST1, the number of registers should be equal to that
2396
       of the structure elements.  */
2397
14.9k
    if (num != 1 && !check_reglist (opnd, mismatch_detail, idx, num, 1))
2398
759
      return false;
2399
14.1k
    break;
2400
14.1k
  case AARCH64_OPND_LVt_AL:
2401
22.4k
  case AARCH64_OPND_LEt:
2402
22.4k
    assert (num >= 1 && num <= 4);
2403
    /* The number of registers should be equal to that of the structure
2404
       elements.  */
2405
22.4k
    if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
2406
0
      return false;
2407
22.4k
    break;
2408
22.4k
  default:
2409
16.7k
    break;
2410
58.5k
  }
2411
57.7k
      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
57.7k
      break;
2417
2418
3.47M
    case AARCH64_OPND_CLASS_IMMEDIATE:
2419
      /* Constraint check on immediate operand.  */
2420
3.47M
      imm = opnd->imm.value;
2421
      /* E.g. imm_0_31 constrains value to be 0..31.  */
2422
3.47M
      if (qualifier_value_in_range_constraint_p (qualifier)
2423
449k
    && !value_in_range_p (imm, get_lower_bound (qualifier),
2424
449k
        get_upper_bound (qualifier)))
2425
49.2k
  {
2426
49.2k
    set_imm_out_of_range_error (mismatch_detail, idx,
2427
49.2k
              get_lower_bound (qualifier),
2428
49.2k
              get_upper_bound (qualifier));
2429
49.2k
    return false;
2430
49.2k
  }
2431
2432
3.42M
      switch (type)
2433
3.42M
  {
2434
438k
  case AARCH64_OPND_AIMM:
2435
438k
    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
438k
    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
438k
    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
438k
    break;
2454
2455
438k
  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.4k
      {
2472
19.4k
        set_sft_amount_out_of_range_error (mismatch_detail, idx,
2473
19.4k
             0, size * 8 - 16);
2474
19.4k
        return false;
2475
19.4k
      }
2476
94.3k
    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.3k
    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.3k
    break;
2489
2490
94.3k
  case AARCH64_OPND_IMM_MOV:
2491
66.4k
      {
2492
66.4k
        int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
2493
66.4k
        imm = opnd->imm.value;
2494
66.4k
        assert (idx == 1);
2495
66.4k
        switch (opcode->op)
2496
66.4k
    {
2497
30.1k
    case OP_MOV_IMM_WIDEN:
2498
30.1k
      imm = ~imm;
2499
      /* Fall through.  */
2500
65.5k
    case OP_MOV_IMM_WIDE:
2501
65.5k
      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.5k
      break;
2508
65.5k
    case OP_MOV_IMM_LOG:
2509
883
      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
883
      break;
2516
883
    default:
2517
0
      assert (0);
2518
0
      return false;
2519
66.4k
    }
2520
66.4k
      }
2521
66.4k
    break;
2522
2523
66.4k
  case AARCH64_OPND_NZCV:
2524
11.5k
  case AARCH64_OPND_CCMP_IMM:
2525
12.8k
  case AARCH64_OPND_EXCEPTION:
2526
1.84M
  case AARCH64_OPND_UNDEFINED:
2527
1.84M
  case AARCH64_OPND_TME_UIMM16:
2528
1.84M
  case AARCH64_OPND_UIMM4:
2529
1.85M
  case AARCH64_OPND_UIMM4_ADDG:
2530
1.85M
  case AARCH64_OPND_UIMM7:
2531
1.86M
  case AARCH64_OPND_UIMM3_OP1:
2532
1.87M
  case AARCH64_OPND_UIMM3_OP2:
2533
1.87M
  case AARCH64_OPND_SVE_UIMM3:
2534
1.90M
  case AARCH64_OPND_SVE_UIMM7:
2535
1.90M
  case AARCH64_OPND_SVE_UIMM8:
2536
1.90M
  case AARCH64_OPND_SVE_UIMM4:
2537
1.91M
  case AARCH64_OPND_SVE_UIMM8_53:
2538
1.91M
  case AARCH64_OPND_CSSC_UIMM8:
2539
1.91M
    size = get_operand_fields_width (get_operand_from_code (type));
2540
1.91M
    assert (size < 32);
2541
1.91M
    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.91M
    break;
2548
2549
1.91M
  case AARCH64_OPND_UIMM10:
2550
    /* Scaled unsigned 10 bits immediate offset.  */
2551
4.57k
    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.57k
    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.57k
    break;
2563
2564
14.3k
  case AARCH64_OPND_SIMM5:
2565
14.9k
  case AARCH64_OPND_SVE_SIMM5:
2566
15.2k
  case AARCH64_OPND_SVE_SIMM5B:
2567
16.0k
  case AARCH64_OPND_SVE_SIMM6:
2568
16.6k
  case AARCH64_OPND_SVE_SIMM8:
2569
18.2k
  case AARCH64_OPND_CSSC_SIMM8:
2570
18.2k
    size = get_operand_fields_width (get_operand_from_code (type));
2571
18.2k
    assert (size < 32);
2572
18.2k
    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.2k
    break;
2580
2581
34.4k
  case AARCH64_OPND_WIDTH:
2582
34.4k
    assert (idx > 1 && opnds[idx-1].type == AARCH64_OPND_IMM
2583
34.4k
      && opnds[0].type == AARCH64_OPND_Rd);
2584
34.4k
    size = get_upper_bound (qualifier);
2585
34.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
34.4k
    break;
2593
2594
299k
  case AARCH64_OPND_LIMM:
2595
342k
  case AARCH64_OPND_SVE_LIMM:
2596
342k
    {
2597
342k
      int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
2598
342k
      uint64_t uimm = opnd->imm.value;
2599
342k
      if (opcode->op == OP_BIC)
2600
0
        uimm = ~uimm;
2601
342k
      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
342k
    }
2608
342k
    break;
2609
2610
342k
  case AARCH64_OPND_IMM0:
2611
673
  case AARCH64_OPND_FPIMM0:
2612
673
    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
673
    break;
2619
2620
748
  case AARCH64_OPND_IMM_ROT1:
2621
17.6k
  case AARCH64_OPND_IMM_ROT2:
2622
26.8k
  case AARCH64_OPND_SVE_IMM_ROT2:
2623
26.8k
    if (opnd->imm.value != 0
2624
19.7k
        && opnd->imm.value != 90
2625
12.7k
        && opnd->imm.value != 180
2626
8.23k
        && 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
26.8k
    break;
2633
2634
26.8k
  case AARCH64_OPND_IMM_ROT3:
2635
1.38k
  case AARCH64_OPND_SVE_IMM_ROT1:
2636
1.77k
  case AARCH64_OPND_SVE_IMM_ROT3:
2637
1.77k
    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.77k
    break;
2644
2645
1.77k
  case AARCH64_OPND_SHLL_IMM:
2646
251
    assert (idx == 2);
2647
251
    size = 8 * aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
2648
251
    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
251
    break;
2655
2656
8.86k
  case AARCH64_OPND_IMM_VLSL:
2657
8.86k
    size = aarch64_get_qualifier_esize (qualifier);
2658
8.86k
    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
8.86k
    break;
2665
2666
14.2k
  case AARCH64_OPND_IMM_VLSR:
2667
14.2k
    size = aarch64_get_qualifier_esize (qualifier);
2668
14.2k
    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.2k
    break;
2674
2675
14.2k
  case AARCH64_OPND_SIMD_IMM:
2676
4.11k
  case AARCH64_OPND_SIMD_IMM_SFT:
2677
    /* Qualifier check.  */
2678
4.11k
    switch (qualifier)
2679
4.11k
      {
2680
3.05k
      case AARCH64_OPND_QLF_LSL:
2681
3.05k
        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.05k
        break;
2688
3.05k
      case AARCH64_OPND_QLF_MSL:
2689
391
        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
391
        break;
2696
674
      case AARCH64_OPND_QLF_NIL:
2697
674
        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
674
        break;
2704
674
      default:
2705
0
        assert (0);
2706
0
        return false;
2707
4.11k
      }
2708
    /* Is the immediate valid?  */
2709
4.11k
    assert (idx == 1);
2710
4.11k
    if (aarch64_get_qualifier_esize (opnds[0].qualifier) != 8)
2711
3.44k
      {
2712
        /* uimm8 or simm8 */
2713
3.44k
        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.44k
      }
2719
674
    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.11k
    switch (opnd->shifter.kind)
2730
4.11k
      {
2731
3.05k
      case AARCH64_MOD_LSL:
2732
3.05k
        size = aarch64_get_qualifier_esize (opnds[0].qualifier);
2733
3.05k
        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.05k
        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.05k
        break;
2745
3.05k
      case AARCH64_MOD_MSL:
2746
        /* Only 8 and 16 are valid shift amount.  */
2747
391
        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
391
        break;
2754
674
      default:
2755
674
        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
674
        break;
2762
4.11k
      }
2763
4.11k
    break;
2764
2765
4.11k
  case AARCH64_OPND_FPIMM:
2766
2.47k
  case AARCH64_OPND_SIMD_FPIMM:
2767
4.37k
  case AARCH64_OPND_SVE_FPIMM8:
2768
4.37k
    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.37k
    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.37k
    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.37k
    break;
2791
2792
4.37k
  case AARCH64_OPND_SVE_AIMM:
2793
2.58k
    min_value = 0;
2794
20.1k
  sve_aimm:
2795
20.1k
    assert (opnd->shifter.kind == AARCH64_MOD_LSL);
2796
20.1k
    size = aarch64_get_qualifier_esize (opnds[0].qualifier);
2797
20.1k
    mask = ~((uint64_t) -1 << (size * 4) << (size * 4));
2798
20.1k
    uvalue = opnd->imm.value;
2799
20.1k
    shift = opnd->shifter.amount;
2800
20.1k
    if (size == 1)
2801
4.21k
      {
2802
4.21k
        if (shift != 0)
2803
143
    {
2804
143
      set_other_error (mismatch_detail, idx,
2805
143
           _("no shift amount allowed for"
2806
143
             " 8-bit constants"));
2807
143
      return false;
2808
143
    }
2809
4.21k
      }
2810
15.9k
    else
2811
15.9k
      {
2812
15.9k
        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
15.9k
        if (shift == 0 && (uvalue & 0xff) == 0)
2819
6.17k
    {
2820
6.17k
      shift = 8;
2821
6.17k
      uvalue = (int64_t) uvalue / 256;
2822
6.17k
    }
2823
15.9k
      }
2824
20.0k
    mask >>= shift;
2825
20.0k
    if ((uvalue & mask) != uvalue && (uvalue | ~mask) != uvalue)
2826
1.78k
      {
2827
1.78k
        set_other_error (mismatch_detail, idx,
2828
1.78k
             _("immediate too big for element size"));
2829
1.78k
        return false;
2830
1.78k
      }
2831
18.2k
    uvalue = (uvalue - min_value) & mask;
2832
18.2k
    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.2k
    break;
2839
2840
18.2k
  case AARCH64_OPND_SVE_ASIMM:
2841
17.5k
    min_value = -128;
2842
17.5k
    goto sve_aimm;
2843
2844
87
  case AARCH64_OPND_SVE_I1_HALF_ONE:
2845
87
    assert (opnd->imm.is_fp);
2846
87
    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
87
    break;
2853
2854
304
  case AARCH64_OPND_SVE_I1_HALF_TWO:
2855
304
    assert (opnd->imm.is_fp);
2856
304
    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
304
    break;
2863
2864
1.17k
  case AARCH64_OPND_SVE_I1_ZERO_ONE:
2865
1.17k
    assert (opnd->imm.is_fp);
2866
1.17k
    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.17k
    break;
2873
2874
1.17k
  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.37k
  case AARCH64_OPND_SVE_LIMM_MOV:
2888
3.37k
    {
2889
3.37k
      int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
2890
3.37k
      uint64_t uimm = opnd->imm.value;
2891
3.37k
      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.37k
      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.37k
    }
2904
3.37k
    break;
2905
2906
6.87k
  case AARCH64_OPND_SVE_PATTERN_SCALED:
2907
6.87k
    assert (opnd->shifter.kind == AARCH64_MOD_MUL);
2908
6.87k
    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
6.87k
    break;
2914
2915
6.87k
  case AARCH64_OPND_SVE_SHLIMM_PRED:
2916
2.33k
  case AARCH64_OPND_SVE_SHLIMM_UNPRED:
2917
3.31k
  case AARCH64_OPND_SVE_SHLIMM_UNPRED_22:
2918
3.31k
    size = aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
2919
3.31k
    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.31k
    break;
2926
2927
3.31k
  case AARCH64_OPND_SME_SHRIMM3:
2928
485
  case AARCH64_OPND_SME_SHRIMM4:
2929
485
    size = 1 << get_operand_fields_width (get_operand_from_code (type));
2930
485
    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
485
    break;
2936
2937
485
  case AARCH64_OPND_SME_SHRIMM5:
2938
1.85k
  case AARCH64_OPND_SVE_SHRIMM_PRED:
2939
4.30k
  case AARCH64_OPND_SVE_SHRIMM_UNPRED:
2940
9.25k
  case AARCH64_OPND_SVE_SHRIMM_UNPRED_22:
2941
9.25k
    num = (type == AARCH64_OPND_SVE_SHRIMM_UNPRED_22) ? 2 : 1;
2942
9.25k
    size = aarch64_get_qualifier_esize (opnds[idx - num].qualifier);
2943
9.25k
    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.25k
    break;
2949
2950
9.25k
  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
188
  case AARCH64_OPND_SME_ZT0_INDEX_MUL_VL:
2965
188
    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
188
    break;
2971
2972
385k
  default:
2973
385k
    break;
2974
3.42M
  }
2975
3.40M
      break;
2976
2977
3.40M
    case AARCH64_OPND_CLASS_SYSTEM:
2978
64.2k
      switch (type)
2979
64.2k
  {
2980
261
  case AARCH64_OPND_PSTATEFIELD:
2981
792
    for (i = 0; aarch64_pstatefields[i].name; ++i)
2982
792
      if (aarch64_pstatefields[i].value == opnd->pstatefield)
2983
261
        break;
2984
261
    assert (aarch64_pstatefields[i].name);
2985
261
    assert (idx == 0 && opnds[1].type == AARCH64_OPND_UIMM4);
2986
261
    max_value = F_GET_REG_MAX_VALUE (aarch64_pstatefields[i].flags);
2987
261
    if (opnds[1].imm.value < 0 || opnds[1].imm.value > max_value)
2988
81
      {
2989
81
        set_imm_out_of_range_error (mismatch_detail, 1, 0, max_value);
2990
81
        return false;
2991
81
      }
2992
180
    break;
2993
45.1k
  case AARCH64_OPND_PRFOP:
2994
45.1k
    if (opcode->iclass == ldst_regoff && opnd->prfop->value >= 24)
2995
905
      {
2996
905
        set_other_error (mismatch_detail, idx,
2997
905
             _("the register-index form of PRFM does"
2998
905
         " not accept opcodes in the range 24-31"));
2999
905
        return false;
3000
905
      }
3001
44.2k
    break;
3002
44.2k
  default:
3003
18.8k
    break;
3004
64.2k
  }
3005
63.2k
      break;
3006
3007
103k
    case AARCH64_OPND_CLASS_SIMD_ELEMENT:
3008
      /* Get the upper bound for the element index.  */
3009
103k
      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.32k
  num = aarch64_get_qualifier_nelem (opnds[0].qualifier)
3013
7.32k
        * aarch64_get_qualifier_esize (opnds[0].qualifier) / 2;
3014
95.9k
      else if (opcode->iclass == lut)
3015
4.35k
  {
3016
4.35k
    size = get_operand_fields_width (get_operand_from_code (type)) - 5;
3017
4.35k
    if (!check_reglane (opnd, mismatch_detail, idx, "v", 0, 31,
3018
4.35k
            0, (1 << size) - 1))
3019
0
      return 0;
3020
4.35k
    break;
3021
4.35k
  }
3022
91.5k
      else
3023
91.5k
  num = 16;
3024
98.9k
      num = num / aarch64_get_qualifier_esize (qualifier) - 1;
3025
98.9k
      assert (aarch64_get_qualifier_nelem (qualifier) == 1);
3026
3027
      /* Index out-of-range.  */
3028
98.9k
      if (!value_in_range_p (opnd->reglane.index, 0, num))
3029
642
  {
3030
642
    set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, num);
3031
642
    return false;
3032
642
  }
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
98.2k
      if (type == AARCH64_OPND_Em16
3042
46.2k
    && (qualifier == AARCH64_OPND_QLF_S_H
3043
9.60k
        || qualifier == AARCH64_OPND_QLF_S_2B)
3044
39.4k
    && !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
98.2k
      if (type == AARCH64_OPND_Em8
3050
3.80k
    && !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
98.2k
      break;
3056
3057
605k
    case AARCH64_OPND_CLASS_MODIFIED_REG:
3058
605k
      assert (idx == 1 || idx == 2);
3059
605k
      switch (type)
3060
605k
  {
3061
60.3k
  case AARCH64_OPND_Rm_EXT:
3062
60.3k
    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
60.3k
    if (!aarch64_stack_pointer_p (opnds + 0)
3074
58.9k
        && (idx != 2 || !aarch64_stack_pointer_p (opnds + 1)))
3075
57.0k
      {
3076
57.0k
        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.0k
        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.0k
      }
3089
60.3k
    assert (opnd->shifter.operator_present  /* Default to LSL.  */
3090
60.3k
      || opnd->shifter.kind == AARCH64_MOD_LSL);
3091
60.3k
    if (!value_in_range_p (opnd->shifter.amount, 0, 4))
3092
8.41k
      {
3093
8.41k
        set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, 4);
3094
8.41k
        return false;
3095
8.41k
      }
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
51.8k
    if (qualifier == AARCH64_OPND_QLF_X
3102
4.35k
        && opnd->shifter.kind != AARCH64_MOD_LSL
3103
4.35k
        && opnd->shifter.kind != AARCH64_MOD_UXTX
3104
1.96k
        && 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
51.8k
    break;
3110
3111
544k
  case AARCH64_OPND_Rm_SFT:
3112
    /* ROR is not available to the shifted register operand in
3113
       arithmetic instructions.  */
3114
544k
    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
544k
    if (opnd->shifter.kind == AARCH64_MOD_ROR
3121
85.6k
        && 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
544k
    num = qualifier == AARCH64_OPND_QLF_W ? 31 : 63;
3128
544k
    if (!value_in_range_p (opnd->shifter.amount, 0, num))
3129
68.2k
      {
3130
68.2k
        set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, num);
3131
68.2k
        return false;
3132
68.2k
      }
3133
475k
    break;
3134
3135
475k
  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
876
    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
876
    break;
3145
3146
876
  default:
3147
0
    break;
3148
605k
  }
3149
528k
      break;
3150
3151
1.82M
    default:
3152
1.82M
      break;
3153
18.8M
    }
3154
3155
18.6M
  return true;
3156
18.8M
}
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.12M
{
3173
8.12M
  int i;
3174
3175
8.12M
  DEBUG_TRACE ("enter");
3176
3177
8.12M
  i = inst->opcode->tied_operand;
3178
3179
8.12M
  if (i > 0)
3180
87.9k
    {
3181
      /* Check for tied_operands with specific opcode iclass.  */
3182
87.9k
      switch (inst->opcode->iclass)
3183
87.9k
        {
3184
        /* For SME LDR and STR instructions #imm must have the same numerical
3185
           value for both operands.
3186
        */
3187
934
        case sme_ldr:
3188
974
        case sme_str:
3189
974
          assert (inst->operands[0].type == AARCH64_OPND_SME_ZA_array_off4);
3190
974
          assert (inst->operands[1].type == AARCH64_OPND_SME_ADDR_RI_U4xVL);
3191
974
          if (inst->operands[0].indexed_za.index.imm
3192
974
              != 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
974
          break;
3202
3203
86.9k
        default:
3204
86.9k
    {
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
86.9k
      enum aarch64_operand_class op_class
3212
86.9k
         = aarch64_get_operand_class (inst->operands[0].type);
3213
86.9k
      assert (aarch64_get_operand_class (inst->operands[i].type)
3214
86.9k
        == op_class);
3215
86.9k
      if (op_class == AARCH64_OPND_CLASS_SVE_REGLIST
3216
86.9k
    ? ((inst->operands[0].reglist.first_regno
3217
358
        != inst->operands[i].reglist.first_regno)
3218
358
       || (inst->operands[0].reglist.num_regs
3219
358
           != inst->operands[i].reglist.num_regs)
3220
358
       || (inst->operands[0].reglist.stride
3221
358
           != inst->operands[i].reglist.stride))
3222
86.9k
    : (inst->operands[0].reg.regno
3223
86.5k
       != 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
86.9k
      break;
3234
86.9k
    }
3235
87.9k
        }
3236
87.9k
    }
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.12M
  int invalid_count;
3249
8.12M
  if (match_operands_qualifier (inst, true /* update_p */,
3250
8.12M
        &invalid_count) == 0)
3251
43.6k
    {
3252
43.6k
      DEBUG_TRACE ("FAIL on operand qualifier matching");
3253
43.6k
      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.6k
      return false;
3264
43.6k
    }
3265
3266
  /* Match operands' constraint.  */
3267
26.7M
  for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
3268
26.7M
    {
3269
26.7M
      enum aarch64_opnd type = inst->opcode->operands[i];
3270
26.7M
      if (type == AARCH64_OPND_NIL)
3271
7.88M
  break;
3272
18.8M
      if (inst->operands[i].skip)
3273
0
  {
3274
0
    DEBUG_TRACE ("skip the incomplete operand %d", i);
3275
0
    continue;
3276
0
  }
3277
18.8M
      if (!operand_general_constraint_met_p (inst->operands, i, type,
3278
18.8M
               inst->opcode, mismatch_detail))
3279
189k
  {
3280
189k
    DEBUG_TRACE ("FAIL on operand %d", i);
3281
189k
    return false;
3282
189k
  }
3283
18.8M
    }
3284
3285
  /* Check constraints involving multiple operands.  */
3286
7.88M
  if (inst->opcode->flags & F_REQUIRES_SP)
3287
5.68k
    {
3288
5.68k
      bool sp_found = false;
3289
16.3k
      for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
3290
16.3k
  {
3291
16.3k
    enum aarch64_opnd type = inst->opcode->operands[i];
3292
16.3k
    if (type == AARCH64_OPND_NIL)
3293
5.28k
      break;
3294
11.0k
    if (aarch64_stack_pointer_p (&(inst->operands[i])))
3295
404
      {
3296
404
        sp_found = true;
3297
404
        break;
3298
404
      }
3299
11.0k
  }
3300
5.68k
      if (!sp_found)
3301
5.28k
  {
3302
5.28k
    set_other_error (mismatch_detail, -1,
3303
5.28k
         _("expected at least one stack pointer operand"));
3304
5.28k
    return false;
3305
5.28k
  }
3306
5.68k
    }
3307
3308
7.88M
  DEBUG_TRACE ("PASS");
3309
3310
7.88M
  return true;
3311
7.88M
}
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
103k
{
3325
103k
  int i;
3326
103k
  const aarch64_opcode *old = inst->opcode;
3327
3328
103k
  inst->opcode = opcode;
3329
3330
  /* Update the operand types.  */
3331
381k
  for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
3332
381k
    {
3333
381k
      inst->operands[i].type = opcode->operands[i];
3334
381k
      if (opcode->operands[i] == AARCH64_OPND_NIL)
3335
103k
  break;
3336
381k
    }
3337
3338
103k
  DEBUG_TRACE ("replace %s with %s", old->name, opcode->name);
3339
3340
103k
  return old;
3341
103k
}
3342
3343
int
3344
aarch64_operand_index (const enum aarch64_opnd *operands, enum aarch64_opnd operand)
3345
184k
{
3346
184k
  int i;
3347
216k
  for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
3348
216k
    if (operands[i] == operand)
3349
179k
      return i;
3350
36.8k
    else if (operands[i] == AARCH64_OPND_NIL)
3351
5.40k
      break;
3352
5.40k
  return -1;
3353
184k
}
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.85M
{
3392
4.85M
  const int has_zr = sp_reg_p ? 0 : 1;
3393
4.85M
  const int is_64 = aarch64_get_qualifier_esize (qualifier) == 4 ? 0 : 1;
3394
4.85M
  return int_reg[has_zr][is_64][regno];
3395
4.85M
}
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.65M
{
3402
1.65M
  const int has_zr = sp_reg_p ? 0 : 1;
3403
1.65M
  return int_reg[has_zr][1][regno];
3404
1.65M
}
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
152k
{
3412
152k
  switch (opnd->shifter.kind)
3413
152k
    {
3414
2.02k
    case AARCH64_MOD_UXTW:
3415
4.54k
    case AARCH64_MOD_SXTW:
3416
4.54k
      return get_int_reg_name (opnd->addr.offset.regno, AARCH64_OPND_QLF_W, 0);
3417
3418
143k
    case AARCH64_MOD_LSL:
3419
148k
    case AARCH64_MOD_SXTX:
3420
148k
      return get_int_reg_name (opnd->addr.offset.regno, AARCH64_OPND_QLF_X, 0);
3421
3422
0
    default:
3423
0
      abort ();
3424
152k
    }
3425
152k
}
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
141k
{
3433
141k
  assert (qualifier == AARCH64_OPND_QLF_S_S
3434
141k
    || qualifier == AARCH64_OPND_QLF_S_D);
3435
141k
  return sve_reg[qualifier == AARCH64_OPND_QLF_S_D][regno];
3436
141k
}
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.42k
{
3469
3.42k
  uint64_t imm = 0;
3470
3.42k
  uint32_t imm8_7, imm8_6_0, imm8_6, imm8_6_repl4;
3471
3472
3.42k
  imm8_7 = (imm8 >> 7) & 0x01;  /* imm8<7>   */
3473
3.42k
  imm8_6_0 = imm8 & 0x7f; /* imm8<6:0> */
3474
3.42k
  imm8_6 = imm8_6_0 >> 6; /* imm8<6>   */
3475
3.42k
  imm8_6_repl4 = (imm8_6 << 3) | (imm8_6 << 2)
3476
3.42k
    | (imm8_6 << 1) | imm8_6; /* Replicate(imm8<6>,4) */
3477
3.42k
  if (size == 8)
3478
751
    {
3479
751
      imm = (imm8_7 << (63-32))   /* imm8<7>  */
3480
751
  | ((imm8_6 ^ 1) << (62-32)) /* NOT(imm8<6)  */
3481
751
  | (imm8_6_repl4 << (58-32)) | (imm8_6 << (57-32))
3482
751
  | (imm8_6 << (56-32)) | (imm8_6 << (55-32)) /* Replicate(imm8<6>,7) */
3483
751
  | (imm8_6_0 << (48-32));  /* imm8<6>:imm8<5:0>    */
3484
751
      imm <<= 32;
3485
751
    }
3486
2.67k
  else if (size == 4 || size == 2)
3487
2.67k
    {
3488
2.67k
      imm = (imm8_7 << 31)  /* imm8<7>              */
3489
2.67k
  | ((imm8_6 ^ 1) << 30)  /* NOT(imm8<6>)         */
3490
2.67k
  | (imm8_6_repl4 << 26)  /* Replicate(imm8<6>,4) */
3491
2.67k
  | (imm8_6_0 << 19); /* imm8<6>:imm8<5:0>    */
3492
2.67k
    }
3493
0
  else
3494
0
    {
3495
      /* An unsupported size.  */
3496
0
      assert (0);
3497
0
    }
3498
3499
3.42k
  return imm;
3500
3.42k
}
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
11.9M
{
3507
11.9M
  const char *txt;
3508
11.9M
  va_list ap;
3509
3510
11.9M
  va_start (ap, fmt);
3511
11.9M
  txt = styler->apply_style (styler, dis_style_register, fmt, ap);
3512
11.9M
  va_end (ap);
3513
3514
11.9M
  return txt;
3515
11.9M
}
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.83M
{
3522
4.83M
  const char *txt;
3523
4.83M
  va_list ap;
3524
3525
4.83M
  va_start (ap, fmt);
3526
4.83M
  txt = styler->apply_style (styler, dis_style_immediate, fmt, ap);
3527
4.83M
  va_end (ap);
3528
3529
4.83M
  return txt;
3530
4.83M
}
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
791k
{
3537
791k
  const char *txt;
3538
791k
  va_list ap;
3539
3540
791k
  va_start (ap, fmt);
3541
791k
  txt = styler->apply_style (styler, dis_style_sub_mnemonic, fmt, ap);
3542
791k
  va_end (ap);
3543
3544
791k
  return txt;
3545
791k
}
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.45M
{
3552
1.45M
  const char *txt;
3553
1.45M
  va_list ap;
3554
3555
1.45M
  va_start (ap, fmt);
3556
1.45M
  txt = styler->apply_style (styler, dis_style_address, fmt, ap);
3557
1.45M
  va_end (ap);
3558
3559
1.45M
  return txt;
3560
1.45M
}
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
412k
{
3569
412k
  const int mask = (prefix[0] == 'p' ? 15 : 31);
3570
412k
  const int num_regs = opnd->reglist.num_regs;
3571
412k
  const int stride = opnd->reglist.stride;
3572
412k
  const int first_reg = opnd->reglist.first_regno;
3573
412k
  const int last_reg = (first_reg + (num_regs - 1) * stride) & mask;
3574
412k
  const char *qlf_name = aarch64_get_qualifier_name (opnd->qualifier);
3575
412k
  char tb[16];  /* Temporary buffer.  */
3576
3577
412k
  assert (opnd->type != AARCH64_OPND_LEt || opnd->reglist.has_index);
3578
412k
  assert (num_regs >= 1 && num_regs <= 4);
3579
3580
  /* Prepare the index if any.  */
3581
412k
  if (opnd->reglist.has_index)
3582
    /* PR 21096: The %100 is to silence a warning about possible truncation.  */
3583
20.7k
    snprintf (tb, sizeof (tb), "[%s]",
3584
20.7k
        style_imm (styler, "%" PRIi64, (opnd->reglist.index % 100)));
3585
391k
  else
3586
391k
    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
412k
  if (stride == 1 && num_regs > 1)
3592
125k
    if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
3593
469
      snprintf (buf, size, "{%s-%s}%s",
3594
469
    style_reg (styler, "%s%d", prefix, first_reg),
3595
469
    style_reg (styler, "%s%d", prefix, last_reg), tb);
3596
124k
    else
3597
124k
      snprintf (buf, size, "{%s-%s}%s",
3598
124k
    style_reg (styler, "%s%d.%s", prefix, first_reg, qlf_name),
3599
124k
    style_reg (styler, "%s%d.%s", prefix, last_reg, qlf_name), tb);
3600
286k
  else
3601
286k
    {
3602
286k
      const int reg0 = first_reg;
3603
286k
      const int reg1 = (first_reg + stride) & mask;
3604
286k
      const int reg2 = (first_reg + stride * 2) & mask;
3605
286k
      const int reg3 = (first_reg + stride * 3) & mask;
3606
3607
286k
      switch (num_regs)
3608
286k
  {
3609
273k
  case 1:
3610
273k
    snprintf (buf, size, "{%s}%s",
3611
273k
        style_reg (styler, "%s%d.%s", prefix, reg0, qlf_name),
3612
273k
        tb);
3613
273k
    break;
3614
8.67k
  case 2:
3615
8.67k
    snprintf (buf, size, "{%s, %s}%s",
3616
8.67k
        style_reg (styler, "%s%d.%s", prefix, reg0, qlf_name),
3617
8.67k
        style_reg (styler, "%s%d.%s", prefix, reg1, qlf_name),
3618
8.67k
        tb);
3619
8.67k
    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
286k
  }
3636
286k
    }
3637
412k
}
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
891k
{
3648
891k
  if (opnd->addr.writeback)
3649
312k
    {
3650
312k
      if (opnd->addr.preind)
3651
159k
        {
3652
159k
    if (opnd->type == AARCH64_OPND_ADDR_SIMM10 && !opnd->addr.offset.imm)
3653
106
      snprintf (buf, size, "[%s]!", style_reg (styler, base));
3654
159k
          else
3655
159k
      snprintf (buf, size, "[%s, %s]!",
3656
159k
          style_reg (styler, base),
3657
159k
          style_imm (styler, "#%d", opnd->addr.offset.imm));
3658
159k
        }
3659
152k
      else
3660
152k
  snprintf (buf, size, "[%s], %s",
3661
152k
      style_reg (styler, base),
3662
152k
      style_imm (styler, "#%d", opnd->addr.offset.imm));
3663
312k
    }
3664
578k
  else
3665
578k
    {
3666
578k
      if (opnd->shifter.operator_present)
3667
87.1k
  {
3668
87.1k
    assert (opnd->shifter.kind == AARCH64_MOD_MUL_VL);
3669
87.1k
    snprintf (buf, size, "[%s, %s, %s]",
3670
87.1k
        style_reg (styler, base),
3671
87.1k
        style_imm (styler, "#%d", opnd->addr.offset.imm),
3672
87.1k
        style_sub_mnem (styler, "mul vl"));
3673
87.1k
  }
3674
491k
      else if (opnd->addr.offset.imm)
3675
399k
  snprintf (buf, size, "[%s, %s]",
3676
399k
      style_reg (styler, base),
3677
399k
      style_imm (styler, "#%d", opnd->addr.offset.imm));
3678
92.2k
      else
3679
92.2k
  snprintf (buf, size, "[%s]", style_reg (styler, base));
3680
578k
    }
3681
891k
}
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
276k
{
3692
276k
  char tb[32];      /* Temporary buffer.  */
3693
276k
  bool print_extend_p = true;
3694
276k
  bool print_amount_p = true;
3695
276k
  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
276k
  if (opnd->type == AARCH64_OPND_SVE_ADDR_ZX && offset != NULL
3700
15.9k
      && strcmp (offset,"xzr") == 0)
3701
310
    {
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
310
      snprintf (buf, size, "[%s]", style_reg (styler, base));
3706
310
    }
3707
275k
  else
3708
275k
    {
3709
275k
      if (!opnd->shifter.amount && (opnd->qualifier != AARCH64_OPND_QLF_S_B
3710
5.31k
            || !opnd->shifter.amount_present))
3711
133k
  {
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
133k
   print_amount_p = false;
3716
   /* Likewise, no need to print the shift operator LSL in such a
3717
      situation.  */
3718
133k
   if (opnd->shifter.kind == AARCH64_MOD_LSL)
3719
82.7k
     print_extend_p = false;
3720
133k
  }
3721
3722
      /* Prepare for the extend/shift.  */
3723
275k
      if (print_extend_p)
3724
193k
  {
3725
193k
    if (print_amount_p)
3726
142k
      snprintf (tb, sizeof (tb), ", %s %s",
3727
142k
          style_sub_mnem (styler, shift_name),
3728
142k
          style_imm (styler, "#%" PRIi64,
3729
    /* PR 21096: The %100 is to silence a warning about possible
3730
       truncation.  */
3731
142k
         (opnd->shifter.amount % 100)));
3732
50.4k
    else
3733
50.4k
      snprintf (tb, sizeof (tb), ", %s",
3734
50.4k
          style_sub_mnem (styler, shift_name));
3735
193k
  }
3736
82.7k
      else
3737
82.7k
  tb[0] = '\0';
3738
3739
275k
      snprintf (buf, size, "[%s, %s%s]", style_reg (styler, base),
3740
275k
    style_reg (styler, offset), tb);
3741
275k
    }
3742
276k
}
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
295
{
3757
295
  static const struct {
3758
295
    unsigned char mask;
3759
295
    char name[7];
3760
295
  } zan[] = {
3761
295
    { 0xff, "za" },
3762
295
    { 0x55, "za0.h" },
3763
295
    { 0xaa, "za1.h" },
3764
295
    { 0x11, "za0.s" },
3765
295
    { 0x22, "za1.s" },
3766
295
    { 0x44, "za2.s" },
3767
295
    { 0x88, "za3.s" },
3768
295
    { 0x01, "za0.d" },
3769
295
    { 0x02, "za1.d" },
3770
295
    { 0x04, "za2.d" },
3771
295
    { 0x08, "za3.d" },
3772
295
    { 0x10, "za4.d" },
3773
295
    { 0x20, "za5.d" },
3774
295
    { 0x40, "za6.d" },
3775
295
    { 0x80, "za7.d" },
3776
295
    { 0x00, " " },
3777
295
  };
3778
295
  int k;
3779
3780
295
  k = snprintf (buf, size, "{");
3781
2.58k
  for (unsigned int i = 0; i < ARRAY_SIZE (zan); i++)
3782
2.58k
    {
3783
2.58k
      if ((mask & zan[i].mask) == zan[i].mask)
3784
852
  {
3785
852
    mask &= ~zan[i].mask;
3786
852
    if (k > 1)
3787
567
      k += snprintf (buf + k, size - k, ", ");
3788
3789
852
    k += snprintf (buf + k, size - k, "%s",
3790
852
       style_reg (styler, zan[i].name));
3791
852
  }
3792
2.58k
      if (mask == 0)
3793
295
        break;
3794
2.58k
    }
3795
295
  snprintf (buf + k, size - k, "}");
3796
295
}
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.6M
{
3818
15.6M
  unsigned int i, num_conds;
3819
15.6M
  const char *name = NULL;
3820
15.6M
  const aarch64_opnd_info *opnd = opnds + idx;
3821
15.6M
  enum aarch64_modifier_kind kind;
3822
15.6M
  uint64_t addr, enum_value;
3823
3824
15.6M
  if (comment != NULL)
3825
15.6M
    {
3826
15.6M
      assert (comment_size > 0);
3827
15.6M
      comment[0] = '\0';
3828
15.6M
    }
3829
0
  else
3830
15.6M
    assert (comment_size == 0);
3831
3832
15.6M
  buf[0] = '\0';
3833
15.6M
  if (pcrel_p)
3834
15.6M
    *pcrel_p = 0;
3835
3836
15.6M
  switch (opnd->type)
3837
15.6M
    {
3838
1.23M
    case AARCH64_OPND_Rd:
3839
1.85M
    case AARCH64_OPND_Rn:
3840
1.98M
    case AARCH64_OPND_Rm:
3841
3.27M
    case AARCH64_OPND_Rt:
3842
3.57M
    case AARCH64_OPND_Rt2:
3843
3.74M
    case AARCH64_OPND_Rs:
3844
3.77M
    case AARCH64_OPND_Ra:
3845
3.77M
    case AARCH64_OPND_Rt_IN_SYS_ALIASES:
3846
3.77M
    case AARCH64_OPND_Rt_LS64:
3847
3.77M
    case AARCH64_OPND_Rt_SYS:
3848
3.77M
    case AARCH64_OPND_PAIRREG:
3849
3.78M
    case AARCH64_OPND_PAIRREG_OR_XZR:
3850
3.78M
    case AARCH64_OPND_SVE_Rm:
3851
3.78M
    case AARCH64_OPND_LSE128_Rt:
3852
3.78M
    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.78M
      if (opnd->type == AARCH64_OPND_Rt_SYS)
3857
411
  {
3858
411
    if (!opnd->present)
3859
15
      break;
3860
411
  }
3861
3.78M
      else if ((opnd->type == AARCH64_OPND_Rt_IN_SYS_ALIASES)
3862
75
         && (opnd->reg.regno
3863
75
       != get_optional_operand_default_value (opcode)))
3864
75
  {
3865
    /* Avoid printing an invalid additional value for Rt in SYS aliases such as
3866
       BRB, provide a helpful comment instead */
3867
75
    snprintf (comment, comment_size, "unpredictable encoding (Rt!=31): #%u", opnd->reg.regno);
3868
75
    break;
3869
75
  }
3870
      /* Omit the operand, e.g. RET.  */
3871
3.78M
      else if (optional_operand_p (opcode, idx)
3872
5.96k
         && (opnd->reg.regno
3873
5.96k
       == get_optional_operand_default_value (opcode)))
3874
2.31k
  break;
3875
3.78M
      assert (opnd->qualifier == AARCH64_OPND_QLF_W
3876
3.77M
        || opnd->qualifier == AARCH64_OPND_QLF_X);
3877
3.77M
      snprintf (buf, size, "%s",
3878
3.77M
    style_reg (styler, get_int_reg_name (opnd->reg.regno,
3879
3.77M
                 opnd->qualifier, 0)));
3880
3.77M
      break;
3881
3882
245k
    case AARCH64_OPND_Rd_SP:
3883
516k
    case AARCH64_OPND_Rn_SP:
3884
525k
    case AARCH64_OPND_Rt_SP:
3885
526k
    case AARCH64_OPND_SVE_Rn_SP:
3886
526k
    case AARCH64_OPND_Rm_SP:
3887
526k
      assert (opnd->qualifier == AARCH64_OPND_QLF_W
3888
526k
        || opnd->qualifier == AARCH64_OPND_QLF_X);
3889
526k
      snprintf (buf, size, "%s",
3890
526k
    style_reg (styler, get_int_reg_name (opnd->reg.regno,
3891
526k
                 opnd->qualifier, 1)));
3892
526k
      break;
3893
3894
29.9k
    case AARCH64_OPND_Rm_EXT:
3895
29.9k
      kind = opnd->shifter.kind;
3896
29.9k
      assert (idx == 1 || idx == 2);
3897
29.9k
      if ((aarch64_stack_pointer_p (opnds)
3898
28.9k
     || (idx == 2 && aarch64_stack_pointer_p (opnds + 1)))
3899
1.89k
    && ((opnd->qualifier == AARCH64_OPND_QLF_W
3900
807
         && opnds[0].qualifier == AARCH64_OPND_QLF_W
3901
457
         && kind == AARCH64_MOD_UXTW)
3902
1.80k
        || (opnd->qualifier == AARCH64_OPND_QLF_X
3903
1.08k
      && kind == AARCH64_MOD_UXTX)))
3904
1.02k
  {
3905
    /* 'LSL' is the preferred form in this case.  */
3906
1.02k
    kind = AARCH64_MOD_LSL;
3907
1.02k
    if (opnd->shifter.amount == 0)
3908
463
      {
3909
        /* Shifter omitted.  */
3910
463
        snprintf (buf, size, "%s",
3911
463
      style_reg (styler,
3912
463
           get_int_reg_name (opnd->reg.regno,
3913
463
                 opnd->qualifier, 0)));
3914
463
        break;
3915
463
      }
3916
1.02k
  }
3917
29.4k
      if (opnd->shifter.amount)
3918
23.1k
  snprintf (buf, size, "%s, %s %s",
3919
23.1k
      style_reg (styler, get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0)),
3920
23.1k
      style_sub_mnem (styler, aarch64_operand_modifiers[kind].name),
3921
23.1k
      style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
3922
6.31k
      else
3923
6.31k
  snprintf (buf, size, "%s, %s",
3924
6.31k
      style_reg (styler, get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0)),
3925
6.31k
      style_sub_mnem (styler, aarch64_operand_modifiers[kind].name));
3926
29.4k
      break;
3927
3928
336k
    case AARCH64_OPND_Rm_SFT:
3929
336k
      assert (opnd->qualifier == AARCH64_OPND_QLF_W
3930
336k
        || opnd->qualifier == AARCH64_OPND_QLF_X);
3931
336k
      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
298k
      else
3936
298k
  snprintf (buf, size, "%s, %s %s",
3937
298k
      style_reg (styler, get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0)),
3938
298k
      style_sub_mnem (styler, aarch64_operand_modifiers[opnd->shifter.kind].name),
3939
298k
      style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
3940
336k
      break;
3941
3942
876
    case AARCH64_OPND_Rm_LSL:
3943
876
      assert (opnd->qualifier == AARCH64_OPND_QLF_X);
3944
876
      assert (opnd->shifter.kind == AARCH64_MOD_LSL);
3945
876
      if (opnd->shifter.amount == 0)
3946
244
  snprintf (buf, size, "%s",
3947
244
      style_reg (styler, get_int_reg_name (opnd->reg.regno,
3948
244
                   opnd->qualifier, 0)));
3949
632
      else
3950
632
  snprintf (buf, size, "%s, %s %s",
3951
632
      style_reg (styler, get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0)),
3952
632
      style_sub_mnem (styler, aarch64_operand_modifiers[opnd->shifter.kind].name),
3953
632
      style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
3954
876
      break;
3955
3956
120k
    case AARCH64_OPND_Fd:
3957
165k
    case AARCH64_OPND_Fn:
3958
220k
    case AARCH64_OPND_Fm:
3959
313k
    case AARCH64_OPND_Fa:
3960
794k
    case AARCH64_OPND_Ft:
3961
1.02M
    case AARCH64_OPND_Ft2:
3962
1.04M
    case AARCH64_OPND_Sd:
3963
1.07M
    case AARCH64_OPND_Sn:
3964
1.07M
    case AARCH64_OPND_Sm:
3965
1.08M
    case AARCH64_OPND_SVE_VZn:
3966
1.08M
    case AARCH64_OPND_SVE_Vd:
3967
1.08M
    case AARCH64_OPND_SVE_Vm:
3968
1.08M
    case AARCH64_OPND_SVE_Vn:
3969
1.08M
      snprintf (buf, size, "%s",
3970
1.08M
    style_reg (styler, "%s%d",
3971
1.08M
         aarch64_get_qualifier_name (opnd->qualifier),
3972
1.08M
         opnd->reg.regno));
3973
1.08M
      break;
3974
3975
10.1k
    case AARCH64_OPND_Va:
3976
300k
    case AARCH64_OPND_Vd:
3977
552k
    case AARCH64_OPND_Vn:
3978
724k
    case AARCH64_OPND_Vm:
3979
724k
      snprintf (buf, size, "%s",
3980
724k
    style_reg (styler, "v%d.%s", opnd->reg.regno,
3981
724k
         aarch64_get_qualifier_name (opnd->qualifier)));
3982
724k
      break;
3983
3984
2.03k
    case AARCH64_OPND_Ed:
3985
7.88k
    case AARCH64_OPND_En:
3986
43.0k
    case AARCH64_OPND_Em:
3987
89.2k
    case AARCH64_OPND_Em16:
3988
93.0k
    case AARCH64_OPND_Em8:
3989
93.0k
      snprintf (buf, size, "%s[%s]",
3990
93.0k
    style_reg (styler, "v%d.%s", opnd->reglane.regno,
3991
93.0k
         aarch64_get_qualifier_name (opnd->qualifier)),
3992
93.0k
    style_imm (styler, "%" PRIi64, opnd->reglane.index));
3993
93.0k
      break;
3994
3995
1.12k
    case AARCH64_OPND_Em_INDEX1_14:
3996
3.39k
    case AARCH64_OPND_Em_INDEX2_13:
3997
4.35k
    case AARCH64_OPND_Em_INDEX3_12:
3998
4.35k
      snprintf (buf, size, "%s[%s]",
3999
4.35k
    style_reg (styler, "v%d", opnd->reglane.regno),
4000
4.35k
    style_imm (styler, "%" PRIi64, opnd->reglane.index));
4001
4.35k
      break;
4002
4003
265
    case AARCH64_OPND_VdD1:
4004
1.21k
    case AARCH64_OPND_VnD1:
4005
1.21k
      snprintf (buf, size, "%s[%s]",
4006
1.21k
    style_reg (styler, "v%d.d", opnd->reg.regno),
4007
1.21k
    style_imm (styler, "1"));
4008
1.21k
      break;
4009
4010
16.7k
    case AARCH64_OPND_LVn:
4011
21.1k
    case AARCH64_OPND_LVn_LUT:
4012
35.3k
    case AARCH64_OPND_LVt:
4013
37.3k
    case AARCH64_OPND_LVt_AL:
4014
57.7k
    case AARCH64_OPND_LEt:
4015
57.7k
      print_register_list (buf, size, opnd, "v", styler);
4016
57.7k
      break;
4017
4018
96.5k
    case AARCH64_OPND_SVE_Pd:
4019
782k
    case AARCH64_OPND_SVE_Pg3:
4020
783k
    case AARCH64_OPND_SVE_Pg4_5:
4021
802k
    case AARCH64_OPND_SVE_Pg4_10:
4022
811k
    case AARCH64_OPND_SVE_Pg4_16:
4023
819k
    case AARCH64_OPND_SVE_Pm:
4024
827k
    case AARCH64_OPND_SVE_Pn:
4025
829k
    case AARCH64_OPND_SVE_Pt:
4026
906k
    case AARCH64_OPND_SME_Pm:
4027
906k
      if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
4028
151k
  snprintf (buf, size, "%s",
4029
151k
      style_reg (styler, "p%d", opnd->reg.regno));
4030
755k
      else if (opnd->qualifier == AARCH64_OPND_QLF_P_Z
4031
444k
         || opnd->qualifier == AARCH64_OPND_QLF_P_M)
4032
647k
  snprintf (buf, size, "%s",
4033
647k
      style_reg (styler, "p%d/%s", opnd->reg.regno,
4034
647k
           aarch64_get_qualifier_name (opnd->qualifier)));
4035
107k
      else
4036
107k
  snprintf (buf, size, "%s",
4037
107k
      style_reg (styler, "p%d.%s", opnd->reg.regno,
4038
107k
           aarch64_get_qualifier_name (opnd->qualifier)));
4039
906k
      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.71k
    case AARCH64_OPND_SME_PNd3:
4046
34.4k
    case AARCH64_OPND_SME_PNg3:
4047
34.4k
    case AARCH64_OPND_SME_PNn:
4048
34.4k
      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
23.9k
      else if (opnd->qualifier == AARCH64_OPND_QLF_P_Z
4052
2.75k
         || opnd->qualifier == AARCH64_OPND_QLF_P_M)
4053
21.2k
  snprintf (buf, size, "%s",
4054
21.2k
      style_reg (styler, "pn%d/%s", opnd->reg.regno,
4055
21.2k
           aarch64_get_qualifier_name (opnd->qualifier)));
4056
2.75k
      else
4057
2.75k
  snprintf (buf, size, "%s",
4058
2.75k
      style_reg (styler, "pn%d.%s", opnd->reg.regno,
4059
2.75k
           aarch64_get_qualifier_name (opnd->qualifier)));
4060
34.4k
      break;
4061
4062
886
    case AARCH64_OPND_SME_Pdx2:
4063
1.01k
    case AARCH64_OPND_SME_PdxN:
4064
1.01k
      print_register_list (buf, size, opnd, "p", styler);
4065
1.01k
      break;
4066
4067
130
    case AARCH64_OPND_SME_PNn3_INDEX1:
4068
180
    case AARCH64_OPND_SME_PNn3_INDEX2:
4069
180
      snprintf (buf, size, "%s[%s]",
4070
180
    style_reg (styler, "pn%d", opnd->reglane.regno),
4071
180
    style_imm (styler, "%" PRIi64, opnd->reglane.index));
4072
180
      break;
4073
4074
7.28k
    case AARCH64_OPND_SVE_Za_5:
4075
16.6k
    case AARCH64_OPND_SVE_Za_16:
4076
453k
    case AARCH64_OPND_SVE_Zd:
4077
498k
    case AARCH64_OPND_SVE_Zm_5:
4078
812k
    case AARCH64_OPND_SVE_Zm_16:
4079
1.30M
    case AARCH64_OPND_SVE_Zn:
4080
1.31M
    case AARCH64_OPND_SVE_Zt:
4081
1.31M
    case AARCH64_OPND_SME_Zm:
4082
1.31M
    case AARCH64_OPND_SME_Zm_17:
4083
1.32M
    case AARCH64_OPND_SME_Zn_6_3:
4084
1.33M
    case AARCH64_OPND_SME_Zm_17_3:
4085
1.33M
      if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
4086
2.84k
       snprintf (buf, size, "%s", style_reg (styler, "z%d", opnd->reg.regno));
4087
1.33M
      else
4088
1.33M
       snprintf (buf, size, "%s",
4089
1.33M
     style_reg (styler, "z%d.%s", opnd->reg.regno,
4090
1.33M
          aarch64_get_qualifier_name (opnd->qualifier)));
4091
1.33M
      break;
4092
4093
12.4k
    case AARCH64_OPND_SVE_ZnxN:
4094
284k
    case AARCH64_OPND_SVE_ZtxN:
4095
305k
    case AARCH64_OPND_SME_Zdnx2:
4096
312k
    case AARCH64_OPND_SME_Zdnx4:
4097
313k
    case AARCH64_OPND_SME_Znx2_6_3:
4098
313k
    case AARCH64_OPND_SME_Zmx2_17_3:
4099
316k
    case AARCH64_OPND_SME_Zmx2:
4100
317k
    case AARCH64_OPND_SME_Zmx4:
4101
317k
    case AARCH64_OPND_SME_Zmx2_INDEX_22:
4102
334k
    case AARCH64_OPND_SME_Znx2:
4103
334k
    case AARCH64_OPND_SME_Znx2_BIT_INDEX:
4104
340k
    case AARCH64_OPND_SME_Znx4:
4105
340k
    case AARCH64_OPND_SME_Zn7xN_UNTYPED:
4106
348k
    case AARCH64_OPND_SME_Ztx2_STRIDED:
4107
353k
    case AARCH64_OPND_SME_Ztx4_STRIDED:
4108
353k
      print_register_list (buf, size, opnd, "z", styler);
4109
353k
      break;
4110
4111
457
    case AARCH64_OPND_SVE_Zm1_23_INDEX:
4112
1.63k
    case AARCH64_OPND_SVE_Zm2_22_INDEX:
4113
6.60k
    case AARCH64_OPND_SVE_Zm3_INDEX:
4114
16.6k
    case AARCH64_OPND_SVE_Zm3_22_INDEX:
4115
17.2k
    case AARCH64_OPND_SVE_Zm3_19_INDEX:
4116
18.2k
    case AARCH64_OPND_SVE_Zm3_12_INDEX:
4117
24.6k
    case AARCH64_OPND_SVE_Zm3_11_INDEX:
4118
28.1k
    case AARCH64_OPND_SVE_Zm3_10_INDEX:
4119
31.7k
    case AARCH64_OPND_SVE_Zm4_11_INDEX:
4120
37.4k
    case AARCH64_OPND_SVE_Zm4_INDEX:
4121
38.4k
    case AARCH64_OPND_SVE_Zn_INDEX:
4122
43.3k
    case AARCH64_OPND_SME_Zk_INDEX:
4123
43.7k
    case AARCH64_OPND_SME_Zm_INDEX1:
4124
46.5k
    case AARCH64_OPND_SME_Zm_INDEX2:
4125
46.9k
    case AARCH64_OPND_SME_Zm_INDEX2_3:
4126
48.8k
    case AARCH64_OPND_SME_Zm_INDEX3_1:
4127
51.6k
    case AARCH64_OPND_SME_Zm_INDEX3_2:
4128
52.3k
    case AARCH64_OPND_SME_Zm_INDEX3_3:
4129
57.3k
    case AARCH64_OPND_SME_Zm_INDEX3_10:
4130
57.7k
    case AARCH64_OPND_SVE_Zn_5_INDEX:
4131
59.7k
    case AARCH64_OPND_SME_Zm_INDEX4_1:
4132
60.8k
    case AARCH64_OPND_SME_Zm_INDEX4_2:
4133
77.3k
    case AARCH64_OPND_SME_Zm_INDEX4_3:
4134
83.7k
    case AARCH64_OPND_SME_Zm_INDEX4_10:
4135
84.0k
    case AARCH64_OPND_SME_Zn_INDEX1_16:
4136
84.2k
    case AARCH64_OPND_SME_Zn_INDEX2_15:
4137
84.9k
    case AARCH64_OPND_SME_Zn_INDEX2_16:
4138
85.0k
    case AARCH64_OPND_SME_Zn_INDEX2_19:
4139
85.2k
    case AARCH64_OPND_SME_Zn_INDEX3_14:
4140
85.4k
    case AARCH64_OPND_SME_Zn_INDEX3_15:
4141
85.6k
    case AARCH64_OPND_SME_Zn_INDEX4_14:
4142
85.6k
      snprintf (buf, size, "%s[%s]",
4143
85.6k
    (opnd->qualifier == AARCH64_OPND_QLF_NIL
4144
85.6k
     ? style_reg (styler, "z%d", opnd->reglane.regno)
4145
85.6k
     : style_reg (styler, "z%d.%s", opnd->reglane.regno,
4146
76.3k
            aarch64_get_qualifier_name (opnd->qualifier))),
4147
85.6k
    style_imm (styler, "%" PRIi64, opnd->reglane.index));
4148
85.6k
      break;
4149
4150
84
    case AARCH64_OPND_SVE_Zn0_INDEX:
4151
171
    case AARCH64_OPND_SVE_Zn1_17_INDEX:
4152
236
    case AARCH64_OPND_SVE_Zn2_18_INDEX:
4153
458
    case AARCH64_OPND_SVE_Zn3_22_INDEX:
4154
539
    case AARCH64_OPND_SVE_Zd0_INDEX:
4155
643
    case AARCH64_OPND_SVE_Zd1_17_INDEX:
4156
725
    case AARCH64_OPND_SVE_Zd2_18_INDEX:
4157
861
    case AARCH64_OPND_SVE_Zd3_22_INDEX:
4158
861
      if (opnd->reglane.index == 0)
4159
251
  snprintf (buf, size, "%s", style_reg (styler, "z%d", opnd->reg.regno));
4160
610
      else
4161
610
  snprintf (buf, size, "%s[%s]",
4162
610
      style_reg (styler, "z%d", opnd->reglane.regno),
4163
610
      style_imm (styler, "%" PRIi64, opnd->reglane.index));
4164
861
      break;
4165
4166
2.03k
    case AARCH64_OPND_SME_ZAda_1b:
4167
74.5k
    case AARCH64_OPND_SME_ZAda_2b:
4168
93.1k
    case AARCH64_OPND_SME_ZAda_3b:
4169
93.1k
      snprintf (buf, size, "%s",
4170
93.1k
    style_reg (styler, "za%d.%s", opnd->reg.regno,
4171
93.1k
         aarch64_get_qualifier_name (opnd->qualifier)));
4172
93.1k
      break;
4173
4174
721
    case AARCH64_OPND_SME_ZA_HV_idx_src:
4175
3.44k
    case AARCH64_OPND_SME_ZA_HV_idx_srcxN:
4176
45.4k
    case AARCH64_OPND_SME_ZA_HV_idx_dest:
4177
46.3k
    case AARCH64_OPND_SME_ZA_HV_idx_destxN:
4178
91.9k
    case AARCH64_OPND_SME_ZA_HV_idx_ldstr:
4179
92.0k
    case AARCH64_OPND_SME_ZA_array_vrsb_1:
4180
92.1k
    case AARCH64_OPND_SME_ZA_array_vrsh_1:
4181
92.2k
    case AARCH64_OPND_SME_ZA_array_vrss_1:
4182
92.4k
    case AARCH64_OPND_SME_ZA_array_vrsd_1:
4183
92.7k
    case AARCH64_OPND_SME_ZA_array_vrsb_2:
4184
92.9k
    case AARCH64_OPND_SME_ZA_array_vrsh_2:
4185
93.1k
    case AARCH64_OPND_SME_ZA_array_vrss_2:
4186
93.5k
    case AARCH64_OPND_SME_ZA_array_vrsd_2:
4187
94.2k
    case AARCH64_OPND_SME_ZA_ARRAY4:
4188
94.2k
      snprintf (buf, size, "%s%s[%s, %s%s%s%s%s]%s",
4189
94.2k
    opnd->type == AARCH64_OPND_SME_ZA_HV_idx_ldstr ? "{" : "",
4190
94.2k
    style_reg (styler, "za%d%c%s%s",
4191
94.2k
         opnd->indexed_za.regno,
4192
94.2k
         opnd->indexed_za.v == 1 ? 'v' : 'h',
4193
94.2k
         opnd->qualifier == AARCH64_OPND_QLF_NIL ? "" : ".",
4194
94.2k
         (opnd->qualifier == AARCH64_OPND_QLF_NIL
4195
94.2k
          ? ""
4196
94.2k
          : aarch64_get_qualifier_name (opnd->qualifier))),
4197
94.2k
    style_reg (styler, "w%d", opnd->indexed_za.index.regno),
4198
94.2k
    style_imm (styler, "%" PRIi64, opnd->indexed_za.index.imm),
4199
94.2k
    opnd->indexed_za.index.countm1 ? ":" : "",
4200
94.2k
    (opnd->indexed_za.index.countm1
4201
94.2k
     ? style_imm (styler, "%d",
4202
5.17k
            opnd->indexed_za.index.imm
4203
5.17k
            + opnd->indexed_za.index.countm1)
4204
94.2k
     : ""),
4205
94.2k
    opnd->indexed_za.group_size ? ", " : "",
4206
94.2k
    opnd->indexed_za.group_size == 2
4207
94.2k
    ? style_sub_mnem (styler, "vgx2")
4208
94.2k
    : opnd->indexed_za.group_size == 4
4209
94.2k
    ? style_sub_mnem (styler, "vgx4") : "",
4210
94.2k
    opnd->type == AARCH64_OPND_SME_ZA_HV_idx_ldstr ? "}" : "");
4211
94.2k
      break;
4212
4213
295
    case AARCH64_OPND_SME_list_of_64bit_tiles:
4214
295
      print_sme_za_list (buf, size, opnd->imm.value, styler);
4215
295
      break;
4216
4217
6.31k
    case AARCH64_OPND_SME_ZA_array_off1x4:
4218
12.0k
    case AARCH64_OPND_SME_ZA_array_off2x2:
4219
19.6k
    case AARCH64_OPND_SME_ZA_array_off2x4:
4220
30.0k
    case AARCH64_OPND_SME_ZA_array_off3_0:
4221
30.3k
    case AARCH64_OPND_SME_ZA_array_off3_5:
4222
51.7k
    case AARCH64_OPND_SME_ZA_array_off3x2:
4223
52.7k
    case AARCH64_OPND_SME_ZA_array_off4:
4224
52.7k
      snprintf (buf, size, "%s[%s, %s%s%s%s%s]",
4225
52.7k
    style_reg (styler, "za%s%s",
4226
52.7k
         opnd->qualifier == AARCH64_OPND_QLF_NIL ? "" : ".",
4227
52.7k
         (opnd->qualifier == AARCH64_OPND_QLF_NIL
4228
52.7k
          ? ""
4229
52.7k
          : aarch64_get_qualifier_name (opnd->qualifier))),
4230
52.7k
    style_reg (styler, "w%d", opnd->indexed_za.index.regno),
4231
52.7k
    style_imm (styler, "%" PRIi64, opnd->indexed_za.index.imm),
4232
52.7k
    opnd->indexed_za.index.countm1 ? ":" : "",
4233
52.7k
    (opnd->indexed_za.index.countm1
4234
52.7k
     ? style_imm (styler, "%d",
4235
41.0k
            opnd->indexed_za.index.imm
4236
41.0k
            + opnd->indexed_za.index.countm1)
4237
52.7k
     : ""),
4238
52.7k
    opnd->indexed_za.group_size ? ", " : "",
4239
52.7k
    opnd->indexed_za.group_size == 2
4240
52.7k
    ? style_sub_mnem (styler, "vgx2")
4241
52.7k
    : opnd->indexed_za.group_size == 4
4242
39.2k
    ? style_sub_mnem (styler, "vgx4") : "");
4243
52.7k
      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.07k
    case AARCH64_OPND_SME_PnT_Wm_imm:
4251
5.07k
      snprintf (buf, size, "%s[%s, %s]",
4252
5.07k
    style_reg (styler, "p%d.%s", opnd->indexed_za.regno,
4253
5.07k
         aarch64_get_qualifier_name (opnd->qualifier)),
4254
5.07k
    style_reg (styler, "w%d", opnd->indexed_za.index.regno),
4255
5.07k
    style_imm (styler, "%" PRIi64, opnd->indexed_za.index.imm));
4256
5.07k
      break;
4257
4258
46
    case AARCH64_OPND_SME_VLxN_10:
4259
2.75k
    case AARCH64_OPND_SME_VLxN_13:
4260
2.75k
      enum_value = opnd->imm.value;
4261
2.75k
      assert (enum_value < ARRAY_SIZE (aarch64_sme_vlxn_array));
4262
2.75k
      snprintf (buf, size, "%s",
4263
2.75k
    style_sub_mnem (styler, aarch64_sme_vlxn_array[enum_value]));
4264
2.75k
      break;
4265
4266
75
    case AARCH64_OPND_BRBOP:
4267
75
      enum_value = opnd->imm.value;
4268
75
      assert (enum_value < ARRAY_SIZE (aarch64_brbop_array));
4269
75
      snprintf (buf, size, "%s",
4270
75
    style_sub_mnem (styler, aarch64_brbop_array[enum_value]));
4271
75
      break;
4272
4273
4.94k
    case AARCH64_OPND_CRn:
4274
9.88k
    case AARCH64_OPND_CRm:
4275
9.88k
      snprintf (buf, size, "%s",
4276
9.88k
    style_reg (styler, "C%" PRIi64, opnd->imm.value));
4277
9.88k
      break;
4278
4279
10.8k
    case AARCH64_OPND_IDX:
4280
11.3k
    case AARCH64_OPND_MASK:
4281
50.7k
    case AARCH64_OPND_IMM:
4282
75.6k
    case AARCH64_OPND_IMM_2:
4283
110k
    case AARCH64_OPND_WIDTH:
4284
114k
    case AARCH64_OPND_UIMM3_OP1:
4285
119k
    case AARCH64_OPND_UIMM3_OP2:
4286
283k
    case AARCH64_OPND_BIT_NUM:
4287
291k
    case AARCH64_OPND_IMM_VLSL:
4288
305k
    case AARCH64_OPND_IMM_VLSR:
4289
305k
    case AARCH64_OPND_SHLL_IMM:
4290
305k
    case AARCH64_OPND_IMM0:
4291
305k
    case AARCH64_OPND_IMMR:
4292
308k
    case AARCH64_OPND_IMMS:
4293
2.14M
    case AARCH64_OPND_UNDEFINED:
4294
2.14M
    case AARCH64_OPND_FBITS:
4295
2.14M
    case AARCH64_OPND_TME_UIMM16:
4296
2.15M
    case AARCH64_OPND_SIMM5:
4297
2.15M
    case AARCH64_OPND_SME_SHRIMM3:
4298
2.15M
    case AARCH64_OPND_SME_SHRIMM4:
4299
2.15M
    case AARCH64_OPND_SME_SHRIMM5:
4300
2.16M
    case AARCH64_OPND_SVE_SHLIMM_PRED:
4301
2.16M
    case AARCH64_OPND_SVE_SHLIMM_UNPRED:
4302
2.16M
    case AARCH64_OPND_SVE_SHLIMM_UNPRED_22:
4303
2.16M
    case AARCH64_OPND_SVE_SHRIMM_PRED:
4304
2.16M
    case AARCH64_OPND_SVE_SHRIMM_UNPRED:
4305
2.17M
    case AARCH64_OPND_SVE_SHRIMM_UNPRED_22:
4306
2.17M
    case AARCH64_OPND_SVE_SIMM5:
4307
2.17M
    case AARCH64_OPND_SVE_SIMM5B:
4308
2.17M
    case AARCH64_OPND_SVE_SIMM6:
4309
2.17M
    case AARCH64_OPND_SVE_SIMM8:
4310
2.17M
    case AARCH64_OPND_SVE_UIMM3:
4311
2.20M
    case AARCH64_OPND_SVE_UIMM7:
4312
2.20M
    case AARCH64_OPND_SVE_UIMM8:
4313
2.20M
    case AARCH64_OPND_SVE_UIMM4:
4314
2.21M
    case AARCH64_OPND_SVE_UIMM8_53:
4315
2.21M
    case AARCH64_OPND_IMM_ROT1:
4316
2.22M
    case AARCH64_OPND_IMM_ROT2:
4317
2.22M
    case AARCH64_OPND_IMM_ROT3:
4318
2.23M
    case AARCH64_OPND_SVE_IMM_ROT1:
4319
2.23M
    case AARCH64_OPND_SVE_IMM_ROT2:
4320
2.23M
    case AARCH64_OPND_SVE_IMM_ROT3:
4321
2.24M
    case AARCH64_OPND_CSSC_SIMM8:
4322
2.24M
    case AARCH64_OPND_CSSC_UIMM8:
4323
2.24M
      snprintf (buf, size, "%s",
4324
2.24M
    style_imm (styler, "#%" PRIi64, opnd->imm.value));
4325
2.24M
      break;
4326
4327
87
    case AARCH64_OPND_SVE_I1_HALF_ONE:
4328
391
    case AARCH64_OPND_SVE_I1_HALF_TWO:
4329
1.56k
    case AARCH64_OPND_SVE_I1_ZERO_ONE:
4330
1.56k
      {
4331
1.56k
  single_conv_t c;
4332
1.56k
  c.i = opnd->imm.value;
4333
1.56k
  snprintf (buf, size, "%s", style_imm (styler, "#%.1f", c.f));
4334
1.56k
  break;
4335
391
      }
4336
4337
377
    case AARCH64_OPND_SVE_PATTERN:
4338
377
      if (optional_operand_p (opcode, idx)
4339
377
    && opnd->imm.value == get_optional_operand_default_value (opcode))
4340
86
  break;
4341
291
      enum_value = opnd->imm.value;
4342
291
      assert (enum_value < ARRAY_SIZE (aarch64_sve_pattern_array));
4343
291
      if (aarch64_sve_pattern_array[enum_value])
4344
134
  snprintf (buf, size, "%s",
4345
134
      style_reg (styler, aarch64_sve_pattern_array[enum_value]));
4346
157
      else
4347
157
  snprintf (buf, size, "%s",
4348
157
      style_imm (styler, "#%" PRIi64, opnd->imm.value));
4349
291
      break;
4350
4351
6.87k
    case AARCH64_OPND_SVE_PATTERN_SCALED:
4352
6.87k
      if (optional_operand_p (opcode, idx)
4353
6.87k
    && !opnd->shifter.operator_present
4354
899
    && opnd->imm.value == get_optional_operand_default_value (opcode))
4355
309
  break;
4356
6.56k
      enum_value = opnd->imm.value;
4357
6.56k
      assert (enum_value < ARRAY_SIZE (aarch64_sve_pattern_array));
4358
6.56k
      if (aarch64_sve_pattern_array[opnd->imm.value])
4359
4.53k
  snprintf (buf, size, "%s",
4360
4.53k
      style_reg (styler,
4361
4.53k
           aarch64_sve_pattern_array[opnd->imm.value]));
4362
2.02k
      else
4363
2.02k
  snprintf (buf, size, "%s",
4364
2.02k
      style_imm (styler, "#%" PRIi64, opnd->imm.value));
4365
6.56k
      if (opnd->shifter.operator_present)
4366
5.97k
  {
4367
5.97k
    size_t len = strlen (buf);
4368
5.97k
    const char *shift_name
4369
5.97k
      = aarch64_operand_modifiers[opnd->shifter.kind].name;
4370
5.97k
    snprintf (buf + len, size - len, ", %s %s",
4371
5.97k
        style_sub_mnem (styler, shift_name),
4372
5.97k
        style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
4373
5.97k
  }
4374
6.56k
      break;
4375
4376
20.6k
    case AARCH64_OPND_SVE_PRFOP:
4377
20.6k
      enum_value = opnd->imm.value;
4378
20.6k
      assert (enum_value < ARRAY_SIZE (aarch64_sve_prfop_array));
4379
20.6k
      if (aarch64_sve_prfop_array[enum_value])
4380
13.3k
  snprintf (buf, size, "%s",
4381
13.3k
      style_reg (styler, aarch64_sve_prfop_array[enum_value]));
4382
7.25k
      else
4383
7.25k
  snprintf (buf, size, "%s",
4384
7.25k
      style_imm (styler, "#%" PRIi64, opnd->imm.value));
4385
20.6k
      break;
4386
4387
66.4k
    case AARCH64_OPND_IMM_MOV:
4388
66.4k
      switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
4389
66.4k
  {
4390
10.7k
  case 4: /* e.g. MOV Wd, #<imm32>.  */
4391
10.7k
      {
4392
10.7k
        int imm32 = opnd->imm.value;
4393
10.7k
        snprintf (buf, size, "%s",
4394
10.7k
      style_imm (styler, "#0x%-20x", imm32));
4395
10.7k
        snprintf (comment, comment_size, "#%d", imm32);
4396
10.7k
      }
4397
10.7k
    break;
4398
55.7k
  case 8: /* e.g. MOV Xd, #<imm64>.  */
4399
55.7k
    snprintf (buf, size, "%s", style_imm (styler, "#0x%-20" PRIx64,
4400
55.7k
            opnd->imm.value));
4401
55.7k
    snprintf (comment, comment_size, "#%" PRIi64, opnd->imm.value);
4402
55.7k
    break;
4403
0
  default:
4404
0
    snprintf (buf, size, "<invalid>");
4405
0
    break;
4406
66.4k
  }
4407
66.4k
      break;
4408
4409
66.4k
    case AARCH64_OPND_FPIMM0:
4410
530
      snprintf (buf, size, "%s", style_imm (styler, "#0.0"));
4411
530
      break;
4412
4413
161k
    case AARCH64_OPND_LIMM:
4414
395k
    case AARCH64_OPND_AIMM:
4415
423k
    case AARCH64_OPND_HALF:
4416
423k
    case AARCH64_OPND_SVE_INV_LIMM:
4417
443k
    case AARCH64_OPND_SVE_LIMM:
4418
446k
    case AARCH64_OPND_SVE_LIMM_MOV:
4419
446k
      if (opnd->shifter.amount)
4420
101k
  snprintf (buf, size, "%s, %s %s",
4421
101k
      style_imm (styler, "#0x%" PRIx64, opnd->imm.value),
4422
101k
      style_sub_mnem (styler, "lsl"),
4423
101k
      style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
4424
345k
      else
4425
345k
  snprintf (buf, size, "%s",
4426
345k
      style_imm (styler, "#0x%" PRIx64, opnd->imm.value));
4427
446k
      break;
4428
4429
674
    case AARCH64_OPND_SIMD_IMM:
4430
4.11k
    case AARCH64_OPND_SIMD_IMM_SFT:
4431
4.11k
      if ((! opnd->shifter.amount && opnd->shifter.kind == AARCH64_MOD_LSL)
4432
2.82k
    || opnd->shifter.kind == AARCH64_MOD_NONE)
4433
1.96k
  snprintf (buf, size, "%s",
4434
1.96k
      style_imm (styler, "#0x%" PRIx64, opnd->imm.value));
4435
2.14k
      else
4436
2.14k
  snprintf (buf, size, "%s, %s %s",
4437
2.14k
      style_imm (styler, "#0x%" PRIx64, opnd->imm.value),
4438
2.14k
      style_sub_mnem (styler, aarch64_operand_modifiers[opnd->shifter.kind].name),
4439
2.14k
      style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
4440
4.11k
      break;
4441
4442
1.20k
    case AARCH64_OPND_SVE_AIMM:
4443
9.72k
    case AARCH64_OPND_SVE_ASIMM:
4444
9.72k
      if (opnd->shifter.amount)
4445
236
  snprintf (buf, size, "%s, %s %s",
4446
236
      style_imm (styler, "#%" PRIi64, opnd->imm.value),
4447
236
      style_sub_mnem (styler, "lsl"),
4448
236
      style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
4449
9.48k
      else
4450
9.48k
  snprintf (buf, size, "%s",
4451
9.48k
      style_imm (styler, "#%" PRIi64, opnd->imm.value));
4452
9.72k
      break;
4453
4454
123
    case AARCH64_OPND_FPIMM:
4455
2.47k
    case AARCH64_OPND_SIMD_FPIMM:
4456
3.42k
    case AARCH64_OPND_SVE_FPIMM8:
4457
3.42k
      switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
4458
3.42k
  {
4459
2.07k
  case 2: /* e.g. FMOV <Hd>, #<imm>.  */
4460
2.07k
      {
4461
2.07k
        half_conv_t c;
4462
2.07k
        c.i = expand_fp_imm (2, opnd->imm.value);
4463
2.07k
        snprintf (buf, size, "%s", style_imm (styler, "#%.18e", c.f));
4464
2.07k
      }
4465
2.07k
    break;
4466
596
  case 4: /* e.g. FMOV <Vd>.4S, #<imm>.  */
4467
596
      {
4468
596
        single_conv_t c;
4469
596
        c.i = expand_fp_imm (4, opnd->imm.value);
4470
596
        snprintf (buf, size, "%s", style_imm (styler, "#%.18e", c.f));
4471
596
      }
4472
596
    break;
4473
751
  case 8: /* e.g. FMOV <Sd>, #<imm>.  */
4474
751
      {
4475
751
        double_conv_t c;
4476
751
        c.i = expand_fp_imm (8, opnd->imm.value);
4477
751
        snprintf (buf, size, "%s", style_imm (styler, "#%.18e", c.d));
4478
751
      }
4479
751
    break;
4480
0
  default:
4481
0
    snprintf (buf, size, "<invalid>");
4482
0
    break;
4483
3.42k
  }
4484
3.42k
      break;
4485
4486
3.42k
    case AARCH64_OPND_CCMP_IMM:
4487
11.5k
    case AARCH64_OPND_NZCV:
4488
12.8k
    case AARCH64_OPND_EXCEPTION:
4489
13.0k
    case AARCH64_OPND_UIMM4:
4490
17.6k
    case AARCH64_OPND_UIMM4_ADDG:
4491
17.7k
    case AARCH64_OPND_UIMM7:
4492
22.3k
    case AARCH64_OPND_UIMM10:
4493
22.3k
      if (optional_operand_p (opcode, idx)
4494
277
    && (opnd->imm.value ==
4495
277
        (int64_t) get_optional_operand_default_value (opcode)))
4496
  /* Omit the operand, e.g. DCPS1.  */
4497
66
  break;
4498
22.2k
      snprintf (buf, size, "%s",
4499
22.2k
    style_imm (styler, "#0x%x", (unsigned int) opnd->imm.value));
4500
22.2k
      break;
4501
4502
20.1k
    case AARCH64_OPND_COND:
4503
20.7k
    case AARCH64_OPND_COND1:
4504
20.7k
      snprintf (buf, size, "%s",
4505
20.7k
    style_sub_mnem (styler, opnd->cond->names[0]));
4506
20.7k
      num_conds = ARRAY_SIZE (opnd->cond->names);
4507
41.5k
      for (i = 1; i < num_conds && opnd->cond->names[i]; ++i)
4508
20.7k
  {
4509
20.7k
    size_t len = comment != NULL ? strlen (comment) : 0;
4510
20.7k
    if (i == 1)
4511
13.7k
      snprintf (comment + len, comment_size - len, "%s = %s",
4512
13.7k
          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.7k
  }
4517
20.7k
      break;
4518
4519
157k
    case AARCH64_OPND_ADDR_ADRP:
4520
157k
      addr = ((pc + AARCH64_PCREL_OFFSET) & ~(uint64_t)0xfff)
4521
157k
  + opnd->imm.value;
4522
157k
      if (pcrel_p)
4523
157k
  *pcrel_p = 1;
4524
157k
      if (address)
4525
157k
  *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
157k
      snprintf (buf, size, "%s", style_addr (styler, "#0x%" PRIx64 , addr));
4531
157k
      break;
4532
4533
70.0k
    case AARCH64_OPND_ADDR_PCREL9:
4534
233k
    case AARCH64_OPND_ADDR_PCREL14:
4535
680k
    case AARCH64_OPND_ADDR_PCREL19:
4536
1.02M
    case AARCH64_OPND_ADDR_PCREL21:
4537
1.30M
    case AARCH64_OPND_ADDR_PCREL26:
4538
1.30M
      addr = pc + AARCH64_PCREL_OFFSET + opnd->imm.value;
4539
1.30M
      if (pcrel_p)
4540
1.30M
  *pcrel_p = 1;
4541
1.30M
      if (address)
4542
1.30M
  *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.30M
      snprintf (buf, size, "%s", style_addr (styler, "#0x%" PRIx64, addr));
4548
1.30M
      break;
4549
4550
221k
    case AARCH64_OPND_ADDR_SIMPLE:
4551
238k
    case AARCH64_OPND_SIMD_ADDR_SIMPLE:
4552
259k
    case AARCH64_OPND_SIMD_ADDR_POST:
4553
259k
      name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
4554
259k
      if (opnd->type == AARCH64_OPND_SIMD_ADDR_POST)
4555
20.5k
  {
4556
20.5k
    if (opnd->addr.offset.is_reg)
4557
17.3k
      snprintf (buf, size, "[%s], %s",
4558
17.3k
          style_reg (styler, name),
4559
17.3k
          style_reg (styler, "x%d", opnd->addr.offset.regno));
4560
3.20k
    else
4561
3.20k
      snprintf (buf, size, "[%s], %s",
4562
3.20k
          style_reg (styler, name),
4563
3.20k
          style_imm (styler, "#%d", opnd->addr.offset.imm));
4564
20.5k
  }
4565
238k
      else
4566
238k
  snprintf (buf, size, "[%s]", style_reg (styler, name));
4567
259k
      break;
4568
4569
26.1k
    case AARCH64_OPND_ADDR_REGOFF:
4570
39.0k
    case AARCH64_OPND_SVE_ADDR_RR:
4571
46.0k
    case AARCH64_OPND_SVE_ADDR_RR_LSL1:
4572
50.8k
    case AARCH64_OPND_SVE_ADDR_RR_LSL2:
4573
67.1k
    case AARCH64_OPND_SVE_ADDR_RR_LSL3:
4574
82.6k
    case AARCH64_OPND_SVE_ADDR_RR_LSL4:
4575
92.2k
    case AARCH64_OPND_SVE_ADDR_RM:
4576
96.7k
    case AARCH64_OPND_SVE_ADDR_RM_LSL1:
4577
101k
    case AARCH64_OPND_SVE_ADDR_RM_LSL2:
4578
105k
    case AARCH64_OPND_SVE_ADDR_RM_LSL3:
4579
105k
    case AARCH64_OPND_SVE_ADDR_RM_LSL4:
4580
122k
    case AARCH64_OPND_SVE_ADDR_RX:
4581
132k
    case AARCH64_OPND_SVE_ADDR_RX_LSL1:
4582
143k
    case AARCH64_OPND_SVE_ADDR_RX_LSL2:
4583
148k
    case AARCH64_OPND_SVE_ADDR_RX_LSL3:
4584
152k
    case AARCH64_OPND_SVE_ADDR_RX_LSL4:
4585
152k
      print_register_offset_address
4586
152k
  (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
4587
152k
   get_offset_int_reg_name (opnd), styler);
4588
152k
      break;
4589
4590
15.9k
    case AARCH64_OPND_SVE_ADDR_ZX:
4591
15.9k
      print_register_offset_address
4592
15.9k
  (buf, size, opnd,
4593
15.9k
   get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier),
4594
15.9k
   get_64bit_int_reg_name (opnd->addr.offset.regno, 0), styler);
4595
15.9k
      break;
4596
4597
22.5k
    case AARCH64_OPND_SVE_ADDR_RZ:
4598
25.2k
    case AARCH64_OPND_SVE_ADDR_RZ_LSL1:
4599
28.0k
    case AARCH64_OPND_SVE_ADDR_RZ_LSL2:
4600
31.2k
    case AARCH64_OPND_SVE_ADDR_RZ_LSL3:
4601
37.1k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW_14:
4602
77.9k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW_22:
4603
79.8k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW1_14:
4604
88.1k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW1_22:
4605
89.4k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW2_14:
4606
96.8k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW2_22:
4607
97.3k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW3_14:
4608
105k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW3_22:
4609
105k
      print_register_offset_address
4610
105k
  (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
4611
105k
   get_addr_sve_reg_name (opnd->addr.offset.regno, opnd->qualifier),
4612
105k
   styler);
4613
105k
      break;
4614
4615
554k
    case AARCH64_OPND_ADDR_SIMM7:
4616
671k
    case AARCH64_OPND_ADDR_SIMM9:
4617
681k
    case AARCH64_OPND_ADDR_SIMM10:
4618
706k
    case AARCH64_OPND_ADDR_SIMM11:
4619
716k
    case AARCH64_OPND_ADDR_SIMM13:
4620
723k
    case AARCH64_OPND_RCPC3_ADDR_OFFSET:
4621
746k
    case AARCH64_OPND_ADDR_OFFSET:
4622
747k
    case AARCH64_OPND_RCPC3_ADDR_OPT_POSTIND:
4623
763k
    case AARCH64_OPND_RCPC3_ADDR_OPT_PREIND_WB:
4624
763k
    case AARCH64_OPND_RCPC3_ADDR_POSTIND:
4625
763k
    case AARCH64_OPND_RCPC3_ADDR_PREIND_WB:
4626
764k
    case AARCH64_OPND_SME_ADDR_RI_U4xVL:
4627
765k
    case AARCH64_OPND_SVE_ADDR_RI_S4x16:
4628
767k
    case AARCH64_OPND_SVE_ADDR_RI_S4x32:
4629
830k
    case AARCH64_OPND_SVE_ADDR_RI_S4xVL:
4630
842k
    case AARCH64_OPND_SVE_ADDR_RI_S4x2xVL:
4631
846k
    case AARCH64_OPND_SVE_ADDR_RI_S4x3xVL:
4632
853k
    case AARCH64_OPND_SVE_ADDR_RI_S4x4xVL:
4633
856k
    case AARCH64_OPND_SVE_ADDR_RI_S6xVL:
4634
860k
    case AARCH64_OPND_SVE_ADDR_RI_S9xVL:
4635
866k
    case AARCH64_OPND_SVE_ADDR_RI_U6:
4636
871k
    case AARCH64_OPND_SVE_ADDR_RI_U6x2:
4637
873k
    case AARCH64_OPND_SVE_ADDR_RI_U6x4:
4638
875k
    case AARCH64_OPND_SVE_ADDR_RI_U6x8:
4639
875k
      print_immediate_offset_address
4640
875k
  (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
4641
875k
   styler);
4642
875k
      break;
4643
4644
5.15k
    case AARCH64_OPND_SVE_ADDR_ZI_U5:
4645
11.4k
    case AARCH64_OPND_SVE_ADDR_ZI_U5x2:
4646
14.4k
    case AARCH64_OPND_SVE_ADDR_ZI_U5x4:
4647
15.8k
    case AARCH64_OPND_SVE_ADDR_ZI_U5x8:
4648
15.8k
      print_immediate_offset_address
4649
15.8k
  (buf, size, opnd,
4650
15.8k
   get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier),
4651
15.8k
   styler);
4652
15.8k
      break;
4653
4654
983
    case AARCH64_OPND_SVE_ADDR_ZZ_LSL:
4655
1.28k
    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
245k
    case AARCH64_OPND_ADDR_UIMM12:
4665
245k
      name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
4666
245k
      if (opnd->addr.offset.imm)
4667
231k
  snprintf (buf, size, "[%s, %s]",
4668
231k
      style_reg (styler, name),
4669
231k
      style_imm (styler, "#%d", opnd->addr.offset.imm));
4670
13.8k
      else
4671
13.8k
  snprintf (buf, size, "[%s]", style_reg (styler, name));
4672
245k
      break;
4673
4674
10.4k
    case AARCH64_OPND_SYSREG:
4675
12.6k
    case AARCH64_OPND_SYSREG128:
4676
12.6k
      {
4677
12.6k
  int min_mismatch = 999;
4678
12.6k
  int best_index = -1;
4679
12.6k
  uint32_t op_flags = opnd->sysreg.flags;
4680
19.7M
  for (i = 0; aarch64_sys_regs[i].name; ++i)
4681
19.7M
    {
4682
19.7M
      const aarch64_sys_reg *sr = aarch64_sys_regs + i;
4683
4684
19.7M
      if (!(aarch64_sys_regs[i].value == opnd->sysreg.value)
4685
1.64k
    || aarch64_sys_reg_deprecated_p (aarch64_sys_regs[i].flags)
4686
1.64k
    || aarch64_sys_reg_alias_p (aarch64_sys_regs[i].flags))
4687
19.6M
        continue;
4688
4689
1.64k
      int mismatch_score = 0;
4690
1.64k
      if (!AARCH64_CPU_HAS_ALL_FEATURES (features, sr->features))
4691
746
        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
1.64k
      if (((sr->flags & F_REG_READ) && (op_flags & F_REG_WRITE))
4695
1.44k
    || ((sr->flags & F_REG_WRITE) && (op_flags & F_REG_READ)))
4696
230
        mismatch_score += 2;
4697
4698
1.64k
      if (mismatch_score < min_mismatch)
4699
1.64k
        {
4700
1.64k
    min_mismatch = mismatch_score;
4701
1.64k
    best_index = i;
4702
1.64k
    if (mismatch_score == 0)
4703
670
      break;
4704
1.64k
        }
4705
1.64k
    }
4706
12.6k
  if (best_index == -1)
4707
10.9k
    {
4708
      /* Use encoding-based name for unrecognised system register.  */
4709
10.9k
      unsigned int value = opnd->sysreg.value;
4710
10.9k
      snprintf (buf, size, "%s",
4711
10.9k
          style_reg (styler, "s%u_%u_c%u_c%u_%u",
4712
10.9k
         (value >> 14) & 0x3, (value >> 11) & 0x7,
4713
10.9k
         (value >> 7) & 0xf, (value >> 3) & 0xf,
4714
10.9k
         value & 0x7));
4715
10.9k
    }
4716
1.62k
  else
4717
1.62k
    {
4718
1.62k
      const aarch64_sys_reg *sr = aarch64_sys_regs + best_index;
4719
1.62k
      snprintf (buf, size, "%s", style_reg (styler, sr->name));
4720
4721
      /* Add a note if we violated read/write constraints.  */
4722
1.62k
      if (notes && min_mismatch)
4723
957
        {
4724
957
    if ((sr->flags & F_REG_READ) && (op_flags & F_REG_WRITE))
4725
180
      *notes = _("writing to a read-only register");
4726
777
    else if ((sr->flags & F_REG_WRITE) && (op_flags & F_REG_READ))
4727
31
      *notes = _("reading from a write-only register");
4728
957
        }
4729
1.62k
    }
4730
12.6k
  break;
4731
10.4k
      }
4732
4733
180
    case AARCH64_OPND_PSTATEFIELD:
4734
711
      for (i = 0; aarch64_pstatefields[i].name; ++i)
4735
711
        if (aarch64_pstatefields[i].value == opnd->pstatefield)
4736
180
          {
4737
            /* PSTATEFIELD name is encoded partially in CRm[3:1] for SVCRSM,
4738
               SVCRZA and SVCRSMZA.  */
4739
180
            uint32_t flags = aarch64_pstatefields[i].flags;
4740
180
            if (flags & F_REG_IN_CRM
4741
0
                && (PSTATE_DECODE_CRM (opnd->sysreg.flags)
4742
0
                    != PSTATE_DECODE_CRM (flags)))
4743
0
              continue;
4744
180
            break;
4745
180
          }
4746
180
      assert (aarch64_pstatefields[i].name);
4747
180
      snprintf (buf, size, "%s",
4748
180
    style_reg (styler, aarch64_pstatefields[i].name));
4749
180
      break;
4750
4751
141
    case AARCH64_OPND_GIC:
4752
141
    case AARCH64_OPND_GICR:
4753
141
    case AARCH64_OPND_GSB:
4754
256
    case AARCH64_OPND_SYSREG_AT:
4755
426
    case AARCH64_OPND_SYSREG_DC:
4756
426
    case AARCH64_OPND_SYSREG_IC:
4757
662
    case AARCH64_OPND_SYSREG_TLBI:
4758
794
    case AARCH64_OPND_SYSREG_TLBIP:
4759
837
    case AARCH64_OPND_SYSREG_PLBI:
4760
837
    case AARCH64_OPND_SYSREG_SR:
4761
837
      snprintf (buf, size, "%s", style_reg (styler, opnd->sysins_op->name));
4762
837
      break;
4763
4764
79
    case AARCH64_OPND_BARRIER:
4765
250
    case AARCH64_OPND_BARRIER_DSB_NXS:
4766
250
      {
4767
250
  if (opnd->barrier->name[0] == '#')
4768
73
    snprintf (buf, size, "%s", style_imm (styler, opnd->barrier->name));
4769
177
  else
4770
177
    snprintf (buf, size, "%s",
4771
177
        style_sub_mnem (styler, opnd->barrier->name));
4772
250
      }
4773
250
      break;
4774
4775
199
    case AARCH64_OPND_BARRIER_ISB:
4776
      /* Operand can be omitted, e.g. in DCPS1.  */
4777
199
      if (! optional_operand_p (opcode, idx)
4778
199
    || (opnd->barrier->value
4779
199
        != get_optional_operand_default_value (opcode)))
4780
49
  snprintf (buf, size, "%s",
4781
49
      style_imm (styler, "#0x%x", opnd->barrier->value));
4782
199
      break;
4783
4784
44.0k
    case AARCH64_OPND_PRFOP:
4785
44.0k
      if ((opnd->prfop->name == NULL)
4786
38.1k
          || (opcode->iclass != ldst_pos && opnd->prfop->value == 0x18))
4787
18.1k
        snprintf (buf, size, "%s",
4788
18.1k
                  style_imm (styler, "#0x%02x", opnd->prfop->value));
4789
25.9k
      else
4790
25.9k
        snprintf (buf, size, "%s", style_sub_mnem (styler, opnd->prfop->name));
4791
44.0k
      break;
4792
4793
749
    case AARCH64_OPND_RPRFMOP:
4794
749
      enum_value = opnd->imm.value;
4795
749
      if (enum_value < ARRAY_SIZE (aarch64_rprfmop_array)
4796
749
    && aarch64_rprfmop_array[enum_value])
4797
124
  snprintf (buf, size, "%s",
4798
124
      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
749
      break;
4803
4804
122
    case AARCH64_OPND_BARRIER_PSB:
4805
122
      snprintf (buf, size, "%s", style_sub_mnem (styler, "csync"));
4806
122
      break;
4807
4808
0
    case AARCH64_OPND_X16:
4809
0
      snprintf (buf, size, "%s", style_reg (styler, "x16"));
4810
0
      break;
4811
4812
1.89k
    case AARCH64_OPND_SME_ZT0:
4813
1.89k
      snprintf (buf, size, "%s", style_reg (styler, "zt0"));
4814
1.89k
      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
188
    case AARCH64_OPND_SME_ZT0_INDEX_MUL_VL:
4821
188
      snprintf (buf, size, "%s[%s, %s]", style_reg (styler, "zt0"),
4822
188
    style_imm (styler, "%d", (int) opnd->imm.value),
4823
188
    style_sub_mnem (styler, "mul vl"));
4824
188
      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
0
    case AARCH64_OPND_NOT_BALANCED_10:
4835
430
    case AARCH64_OPND_NOT_BALANCED_17:
4836
430
      if (opnd->imm.value)
4837
64
  snprintf (buf, size, "%s", style_sub_mnem (styler, "nb"));
4838
430
      break;
4839
4840
253
    case AARCH64_OPND_BTI_TARGET:
4841
253
      snprintf (buf, size, "%s",
4842
253
    style_sub_mnem (styler, opnd->hint_option->name));
4843
253
      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.26k
    case AARCH64_OPND_MOPS_ADDR_Rd:
4856
16.9k
    case AARCH64_OPND_MOPS_ADDR_Rs:
4857
16.9k
      snprintf (buf, size, "[%s]!",
4858
16.9k
    style_reg (styler,
4859
16.9k
         get_int_reg_name (opnd->reg.regno,
4860
16.9k
               AARCH64_OPND_QLF_X, 0)));
4861
16.9k
      break;
4862
4863
9.26k
    case AARCH64_OPND_MOPS_WB_Rn:
4864
9.26k
      snprintf (buf, size, "%s!",
4865
9.26k
    style_reg (styler, get_int_reg_name (opnd->reg.regno,
4866
9.26k
                 AARCH64_OPND_QLF_X, 0)));
4867
9.26k
      break;
4868
4869
0
    default:
4870
0
      snprintf (buf, size, "<invalid>");
4871
0
      break;
4872
15.6M
    }
4873
15.6M
}
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
1.64k
{
4916
1.64k
  return (reg_flags & F_DEPRECATED) != 0;
4917
1.64k
}
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
1.64k
{
4928
1.64k
  return (reg_flags & F_REG_ALIAS) != 0;
4929
1.64k
}
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.32k
{
5283
1.32k
  return (sys_ins_reg->flags & F_HASXT) != 0;
5284
1.32k
}
5285
5286
bool
5287
aarch64_sys_ins_reg_tlbid_xt (const aarch64_sys_ins_reg *sys_ins_reg)
5288
1.03k
{
5289
1.03k
  return (sys_ins_reg->flags & F_TLBID_XT) != 0;
5290
1.03k
}
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
159k
#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.1k
{
5335
53.1k
  int t  = BITS (insn, 4, 0);
5336
53.1k
  int n  = BITS (insn, 9, 5);
5337
53.1k
  int t2 = BITS (insn, 14, 10);
5338
5339
53.1k
  if (BIT (insn, 23))
5340
15.7k
    {
5341
      /* Write back enabled.  */
5342
15.7k
      if ((t == n || t2 == n) && n != 31)
5343
1.38k
  return ERR_UND;
5344
15.7k
    }
5345
5346
51.8k
  if (BIT (insn, 22))
5347
51.8k
    {
5348
      /* Load */
5349
51.8k
      if (t == t2)
5350
5.11k
  return ERR_UND;
5351
51.8k
    }
5352
5353
46.7k
  return ERR_OK;
5354
51.8k
}
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.25k
{
5365
3.25k
  const aarch64_insn undef_pattern = 0x3;
5366
3.25k
  aarch64_insn value;
5367
5368
3.25k
  assert (inst->opcode);
5369
3.25k
  assert (inst->opcode->operands[2] == AARCH64_OPND_Em);
5370
3.25k
  value = encoding ? inst->value : insn;
5371
3.25k
  assert (value);
5372
5373
3.25k
  if (undef_pattern == extract_fields (value, 0, 2, FLD_sz, FLD_L))
5374
866
    return ERR_UND;
5375
5376
2.38k
  return ERR_OK;
5377
3.25k
}
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.1k
{
5392
11.1k
  int rd, rs, rn;
5393
5394
11.1k
  rd = inst->operands[0].reg.regno;
5395
11.1k
  rs = inst->operands[1].reg.regno;
5396
11.1k
  rn = inst->operands[2].reg.regno;
5397
11.1k
  if (rd == rs || rd == rn || rs == rn)
5398
1.99k
    {
5399
1.99k
      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5400
1.99k
      mismatch_detail->error
5401
1.99k
  = _("the three register operands must be distinct from one another");
5402
1.99k
      mismatch_detail->index = -1;
5403
1.99k
      return ERR_UND;
5404
1.99k
    }
5405
5406
9.13k
  return ERR_OK;
5407
11.1k
}
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
220
{
5422
220
  int rd, rn;
5423
5424
220
  rd = inst->operands[0].reg.regno;
5425
220
  rn = inst->operands[1].reg.regno;
5426
220
  if (rd == rn)
5427
88
    {
5428
88
      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5429
88
      mismatch_detail->error
5430
88
  = _("the two register operands must be distinct from each other");
5431
88
      mismatch_detail->index = -1;
5432
88
      return ERR_UND;
5433
88
    }
5434
5435
132
  return ERR_OK;
5436
220
}
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.25k
{
5444
9.25k
  insn_sequence->instr[insn_sequence->num_added_insns++] = *inst;
5445
9.25k
}
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
18.8k
{
5455
18.8k
  int num_req_entries = 0;
5456
5457
18.8k
  if (insn_sequence->instr)
5458
8.86k
    {
5459
8.86k
      XDELETE (insn_sequence->instr);
5460
8.86k
      insn_sequence->instr = NULL;
5461
8.86k
    }
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
18.8k
  if (inst && inst->opcode->constraints & C_SCAN_MOVPRFX)
5467
3.79k
    num_req_entries = 1;
5468
18.8k
  if (inst && (inst->opcode->constraints & C_SCAN_MOPS_PME) == C_SCAN_MOPS_P)
5469
5.07k
    num_req_entries = 2;
5470
5471
18.8k
  insn_sequence->num_added_insns = 0;
5472
18.8k
  insn_sequence->num_allocated_insns = num_req_entries;
5473
5474
18.8k
  if (num_req_entries != 0)
5475
8.86k
    {
5476
8.86k
      insn_sequence->instr = XCNEWVEC (aarch64_inst, num_req_entries);
5477
8.86k
      add_insn_to_sequence (inst, insn_sequence);
5478
8.86k
    }
5479
18.8k
}
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
254k
{
5495
254k
  const struct aarch64_opcode *opcode;
5496
254k
  const struct aarch64_inst *prev_insn;
5497
254k
  int i;
5498
5499
254k
  opcode = inst->opcode;
5500
254k
  if (insn_sequence->instr)
5501
8.34k
    prev_insn = insn_sequence->instr + (insn_sequence->num_added_insns - 1);
5502
245k
  else
5503
245k
    prev_insn = NULL;
5504
5505
254k
  if (prev_insn
5506
8.34k
      && (prev_insn->opcode->constraints & C_SCAN_MOPS_PME)
5507
4.60k
      && prev_insn->opcode != opcode - 1)
5508
4.21k
    {
5509
4.21k
      mismatch_detail->kind = AARCH64_OPDE_EXPECTED_A_AFTER_B;
5510
4.21k
      mismatch_detail->error = NULL;
5511
4.21k
      mismatch_detail->index = -1;
5512
4.21k
      mismatch_detail->data[0].s = prev_insn->opcode[1].name;
5513
4.21k
      mismatch_detail->data[1].s = prev_insn->opcode->name;
5514
4.21k
      mismatch_detail->non_fatal = true;
5515
4.21k
      return false;
5516
4.21k
    }
5517
5518
250k
  if (opcode->constraints & C_SCAN_MOPS_PME)
5519
4.18k
    {
5520
4.18k
      if (is_new_section || !prev_insn || prev_insn->opcode != opcode - 1)
5521
3.80k
  {
5522
3.80k
    mismatch_detail->kind = AARCH64_OPDE_A_SHOULD_FOLLOW_B;
5523
3.80k
    mismatch_detail->error = NULL;
5524
3.80k
    mismatch_detail->index = -1;
5525
3.80k
    mismatch_detail->data[0].s = opcode->name;
5526
3.80k
    mismatch_detail->data[1].s = opcode[-1].name;
5527
3.80k
    mismatch_detail->non_fatal = true;
5528
3.80k
    return false;
5529
3.80k
  }
5530
5531
823
      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
746
  if ((opcode->operands[i] == AARCH64_OPND_MOPS_ADDR_Rd
5535
362
       || opcode->operands[i] == AARCH64_OPND_MOPS_ADDR_Rs
5536
176
       || opcode->operands[i] == AARCH64_OPND_MOPS_WB_Rn)
5537
746
      && prev_insn->operands[i].reg.regno != inst->operands[i].reg.regno)
5538
307
    {
5539
307
      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5540
307
      if (opcode->operands[i] == AARCH64_OPND_MOPS_ADDR_Rd)
5541
198
        mismatch_detail->error = _("destination register differs from "
5542
109
           "preceding instruction");
5543
109
      else if (opcode->operands[i] == AARCH64_OPND_MOPS_ADDR_Rs)
5544
10
        mismatch_detail->error = _("source register differs from "
5545
99
           "preceding instruction");
5546
99
      else
5547
99
        mismatch_detail->error = _("size register differs from "
5548
307
           "preceding instruction");
5549
307
      mismatch_detail->index = i;
5550
307
      mismatch_detail->non_fatal = true;
5551
307
      return false;
5552
307
    }
5553
384
    }
5554
5555
245k
  return true;
5556
250k
}
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.01M
{
5578
7.01M
  assert (inst);
5579
7.01M
  assert (inst->opcode);
5580
5581
7.01M
  const struct aarch64_opcode *opcode = inst->opcode;
5582
7.01M
  if (!opcode->constraints && !insn_sequence->instr)
5583
6.74M
    return ERR_OK;
5584
5585
7.01M
  assert (insn_sequence);
5586
5587
263k
  enum err_type res = ERR_OK;
5588
5589
  /* This instruction puts a constraint on the insn_sequence.  */
5590
263k
  if (opcode->flags & F_SCAN)
5591
8.86k
    {
5592
8.86k
      if (insn_sequence->instr)
5593
914
  {
5594
914
    mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5595
914
    mismatch_detail->error = _("instruction opens new dependency "
5596
914
             "sequence without ending previous one");
5597
914
    mismatch_detail->index = -1;
5598
914
    mismatch_detail->non_fatal = true;
5599
914
    res = ERR_VFI;
5600
914
  }
5601
5602
8.86k
      init_insn_sequence (inst, insn_sequence);
5603
8.86k
      return res;
5604
8.86k
    }
5605
5606
263k
  bool is_new_section = (!encoding && pc == 0);
5607
254k
  if (!verify_mops_pme_sequence (inst, is_new_section, mismatch_detail,
5608
254k
         insn_sequence))
5609
8.32k
    {
5610
8.32k
      res = ERR_VFI;
5611
8.32k
      if ((opcode->constraints & C_SCAN_MOPS_PME) != C_SCAN_MOPS_M)
5612
6.25k
  init_insn_sequence (NULL, insn_sequence);
5613
8.32k
    }
5614
5615
  /* Verify constraints on an existing sequence.  */
5616
254k
  if (insn_sequence->instr)
5617
4.13k
    {
5618
4.13k
      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.13k
      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.13k
      if (inst_opcode->constraints & C_SCAN_MOVPRFX)
5635
3.74k
  {
5636
    /* Check to see if the MOVPRFX SVE instruction is followed by an SVE
5637
       instruction for better error messages.  */
5638
3.74k
    bool sve_operand_p = false;
5639
14.8k
    for (int i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
5640
13.2k
      {
5641
13.2k
        enum aarch64_operand_class op_class
5642
13.2k
    = aarch64_get_operand_class (opcode->operands[i]);
5643
13.2k
        if (op_class == AARCH64_OPND_CLASS_SVE_REG
5644
11.6k
      || op_class == AARCH64_OPND_CLASS_SVE_REGLIST
5645
11.2k
      || op_class == AARCH64_OPND_CLASS_PRED_REG)
5646
2.17k
    {
5647
2.17k
      sve_operand_p = true;
5648
2.17k
      break;
5649
2.17k
    }
5650
13.2k
      }
5651
5652
3.74k
    if (!sve_operand_p)
5653
1.57k
      {
5654
1.57k
        mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5655
1.57k
        mismatch_detail->error = _("SVE instruction expected after "
5656
1.57k
           "`movprfx'");
5657
1.57k
        mismatch_detail->index = -1;
5658
1.57k
        mismatch_detail->non_fatal = true;
5659
1.57k
        res = ERR_VFI;
5660
1.57k
        goto done;
5661
1.57k
      }
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.17k
    if (!(opcode->constraints & C_SCAN_MOVPRFX))
5666
731
      {
5667
731
        mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5668
731
        mismatch_detail->error = _("SVE `movprfx' compatible instruction "
5669
731
           "expected");
5670
731
        mismatch_detail->index = -1;
5671
731
        mismatch_detail->non_fatal = true;
5672
731
        res = ERR_VFI;
5673
731
        goto done;
5674
731
      }
5675
5676
    /* Next check for usage of the predicate register.  */
5677
1.43k
    aarch64_opnd_info blk_dest = insn_sequence->instr->operands[0];
5678
1.43k
    aarch64_opnd_info blk_pred, inst_pred;
5679
1.43k
    memset (&blk_pred, 0, sizeof (aarch64_opnd_info));
5680
1.43k
    memset (&inst_pred, 0, sizeof (aarch64_opnd_info));
5681
1.43k
    bool predicated = false;
5682
1.43k
    assert (blk_dest.type == AARCH64_OPND_SVE_Zd);
5683
5684
    /* Determine if the movprfx instruction used is predicated or not.  */
5685
1.43k
    if (insn_sequence->instr->operands[1].type == AARCH64_OPND_SVE_Pg3)
5686
1.33k
      {
5687
1.33k
        predicated = true;
5688
1.33k
        blk_pred = insn_sequence->instr->operands[1];
5689
1.33k
      }
5690
5691
1.43k
    unsigned char max_elem_size = 0;
5692
1.43k
    unsigned char current_elem_size;
5693
1.43k
    int num_op_used = 0, last_op_usage = 0;
5694
1.43k
    int i, inst_pred_idx = -1;
5695
1.43k
    int num_ops = aarch64_num_of_operands (opcode);
5696
6.52k
    for (i = 0; i < num_ops; i++)
5697
5.08k
      {
5698
5.08k
        aarch64_opnd_info inst_op = inst->operands[i];
5699
5.08k
        switch (inst_op.type)
5700
5.08k
    {
5701
1.79k
      case AARCH64_OPND_SVE_Zd:
5702
2.35k
      case AARCH64_OPND_SVE_Zm_5:
5703
2.59k
      case AARCH64_OPND_SVE_Zm_16:
5704
3.16k
      case AARCH64_OPND_SVE_Zn:
5705
3.16k
      case AARCH64_OPND_SVE_Zt:
5706
3.24k
      case AARCH64_OPND_SVE_Vm:
5707
3.36k
      case AARCH64_OPND_SVE_Vn:
5708
3.36k
      case AARCH64_OPND_Va:
5709
3.36k
      case AARCH64_OPND_Vn:
5710
3.36k
      case AARCH64_OPND_Vm:
5711
3.36k
      case AARCH64_OPND_Sn:
5712
3.36k
      case AARCH64_OPND_Sm:
5713
3.36k
        if (inst_op.reg.regno == blk_dest.reg.regno)
5714
853
          {
5715
853
      num_op_used++;
5716
853
      last_op_usage = i;
5717
853
          }
5718
3.36k
        current_elem_size
5719
3.36k
          = aarch64_get_qualifier_esize (inst_op.qualifier);
5720
3.36k
        if (current_elem_size > max_elem_size)
5721
1.43k
          max_elem_size = current_elem_size;
5722
3.36k
        break;
5723
0
      case AARCH64_OPND_SVE_Pd:
5724
1.06k
      case AARCH64_OPND_SVE_Pg3:
5725
1.06k
      case AARCH64_OPND_SVE_Pg4_5:
5726
1.06k
      case AARCH64_OPND_SVE_Pg4_10:
5727
1.13k
      case AARCH64_OPND_SVE_Pg4_16:
5728
1.13k
      case AARCH64_OPND_SVE_Pm:
5729
1.13k
      case AARCH64_OPND_SVE_Pn:
5730
1.13k
      case AARCH64_OPND_SVE_Pt:
5731
1.13k
      case AARCH64_OPND_SME_Pm:
5732
1.13k
        inst_pred = inst_op;
5733
1.13k
        inst_pred_idx = i;
5734
1.13k
        break;
5735
590
      default:
5736
590
        break;
5737
5.08k
    }
5738
5.08k
      }
5739
5740
1.43k
     assert (max_elem_size != 0);
5741
1.43k
     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.43k
     current_elem_size
5745
1.43k
       = opcode->constraints & C_MAX_ELEM
5746
1.43k
         ? max_elem_size
5747
1.43k
         : aarch64_get_qualifier_esize (inst_dest.qualifier);
5748
5749
    /* If movprfx is predicated do some extra checks.  */
5750
1.43k
    if (predicated)
5751
1.33k
      {
5752
        /* The instruction must be predicated.  */
5753
1.33k
        if (inst_pred_idx < 0)
5754
307
    {
5755
307
      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5756
307
      mismatch_detail->error = _("predicated instruction expected "
5757
307
               "after `movprfx'");
5758
307
      mismatch_detail->index = -1;
5759
307
      mismatch_detail->non_fatal = true;
5760
307
      res = ERR_VFI;
5761
307
      goto done;
5762
307
    }
5763
5764
        /* The instruction must have a merging predicate.  */
5765
1.03k
        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
997
        if (blk_pred.reg.regno != inst_pred.reg.regno)
5778
516
    {
5779
516
      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5780
516
      mismatch_detail->error = _("predicate register differs "
5781
516
               "from that in preceding "
5782
516
               "`movprfx'");
5783
516
      mismatch_detail->index = inst_pred_idx;
5784
516
      mismatch_detail->non_fatal = true;
5785
516
      res = ERR_VFI;
5786
516
      goto done;
5787
516
    }
5788
997
      }
5789
5790
    /* Destructive operations by definition must allow one usage of the
5791
       same register.  */
5792
582
    int allowed_usage
5793
582
      = aarch64_is_destructive_by_operands (opcode) ? 2 : 1;
5794
5795
    /* Operand is not used at all.  */
5796
582
    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
463
    if (blk_dest.reg.regno != inst_dest.reg.regno)
5810
89
      {
5811
89
        mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5812
89
        mismatch_detail->error = _("output register of preceding "
5813
89
           "`movprfx' expected as output");
5814
89
        mismatch_detail->index = 0;
5815
89
        mismatch_detail->non_fatal = true;
5816
89
        res = ERR_VFI;
5817
89
        goto done;
5818
89
      }
5819
5820
    /* Operand used more than allowed for the specific opcode type.  */
5821
374
    if (num_op_used > allowed_usage)
5822
125
      {
5823
125
        mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5824
125
        mismatch_detail->error = _("output register of preceding "
5825
125
           "`movprfx' used as input");
5826
125
        mismatch_detail->index = last_op_usage;
5827
125
        mismatch_detail->non_fatal = true;
5828
125
        res = ERR_VFI;
5829
125
        goto done;
5830
125
      }
5831
5832
    /* Now the only thing left is the qualifiers checks.  The register
5833
       must have the same maximum element size.  */
5834
249
    if (inst_dest.qualifier != AARCH64_OPND_QLF_NIL
5835
249
        && blk_dest.qualifier != AARCH64_OPND_QLF_NIL
5836
151
        && current_elem_size
5837
151
     != 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
249
  }
5848
5849
4.13k
    done:
5850
4.13k
      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.74k
  init_insn_sequence (NULL, insn_sequence);
5854
389
      else
5855
389
  add_insn_to_sequence (inst, insn_sequence);
5856
4.13k
    }
5857
5858
254k
  return res;
5859
254k
}
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.74k
{
5869
8.74k
  int64_t svalue = uvalue;
5870
8.74k
  uint64_t upper = (uint64_t) -1 << (esize * 4) << (esize * 4);
5871
5872
8.74k
  if ((uvalue & ~upper) != uvalue && (uvalue | upper) != uvalue)
5873
0
    return false;
5874
8.74k
  if (esize <= 4 || (uint32_t) uvalue == (uint32_t) (uvalue >> 32))
5875
6.82k
    {
5876
6.82k
      svalue = (int32_t) uvalue;
5877
6.82k
      if (esize <= 2 || (uint16_t) uvalue == (uint16_t) (uvalue >> 16))
5878
1.62k
  {
5879
1.62k
    svalue = (int16_t) uvalue;
5880
1.62k
    if (esize == 1 || (uint8_t) uvalue == (uint8_t) (uvalue >> 8))
5881
1.05k
      return false;
5882
1.62k
  }
5883
6.82k
    }
5884
7.69k
  if ((svalue & 0xff) == 0)
5885
3.57k
    svalue /= 256;
5886
7.69k
  return svalue < -128 || svalue >= 128;
5887
8.74k
}
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"