Coverage Report

Created: 2026-07-25 10:20

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
844k
{
132
844k
  return (qualifier >= AARCH64_OPND_QLF_V_8B
133
675k
    && qualifier <= AARCH64_OPND_QLF_V_1Q);
134
844k
}
135
136
static inline bool
137
fp_qualifier_p (enum aarch64_opnd_qualifier qualifier)
138
1.05k
{
139
1.05k
  return (qualifier >= AARCH64_OPND_QLF_S_B
140
1.05k
    && qualifier <= AARCH64_OPND_QLF_S_Q);
141
1.05k
}
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
365k
{
169
365k
  if (vector_qualifier_p (qualifiers[0]))
170
364k
    {
171
      /* e.g. v.4s, v.4s, v.4s
172
     or v.4h, v.4h, v.h[3].  */
173
364k
      if (qualifiers[0] == qualifiers[1]
174
175k
    && vector_qualifier_p (qualifiers[2])
175
125k
    && (aarch64_get_qualifier_esize (qualifiers[0])
176
125k
        == aarch64_get_qualifier_esize (qualifiers[2])))
177
119k
  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
245k
      if (vector_qualifier_p (qualifiers[1])
182
175k
    && aarch64_get_qualifier_esize (qualifiers[0]) != 0
183
175k
    && (aarch64_get_qualifier_esize (qualifiers[0])
184
175k
        == aarch64_get_qualifier_esize (qualifiers[1]) << 1))
185
63.6k
  return DP_VECTOR_LONG;
186
      /* e.g. v.8h, v.8h, v.8b.  */
187
181k
      if (qualifiers[0] == qualifiers[1]
188
56.6k
    && vector_qualifier_p (qualifiers[2])
189
5.84k
    && aarch64_get_qualifier_esize (qualifiers[0]) != 0
190
5.84k
    && (aarch64_get_qualifier_esize (qualifiers[0])
191
5.84k
        == aarch64_get_qualifier_esize (qualifiers[2]) << 1))
192
5.84k
  return DP_VECTOR_WIDE;
193
181k
    }
194
1.05k
  else if (fp_qualifier_p (qualifiers[0]))
195
1.05k
    {
196
      /* e.g. SADDLV <V><d>, <Vn>.<T>.  */
197
1.05k
      if (vector_qualifier_p (qualifiers[1])
198
865
    && (qualifiers[2] == AARCH64_OPND_QLF_UNUSED))
199
865
  return DP_VECTOR_ACROSS_LANES;
200
1.05k
    }
201
202
176k
  return DP_UNKNOWN;
203
365k
}
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
365k
{
216
365k
  return
217
365k
    significant_operand_index [get_data_pattern (opcode->qualifiers_list[0])];
218
365k
}
219

220
enum aarch64_operand_class
221
aarch64_get_operand_class (enum aarch64_opnd type)
222
3.03M
{
223
3.03M
  return aarch64_operands[type].op_class;
224
3.03M
}
225
226
const char *
227
aarch64_get_operand_name (enum aarch64_opnd type)
228
0
{
229
0
  return aarch64_operands[type].name;
230
0
}
231
232
/* Get operand description string.
233
   This is usually for the diagnosis purpose.  */
234
const char *
235
aarch64_get_operand_desc (enum aarch64_opnd type)
236
0
{
237
0
  return aarch64_operands[type].desc;
238
0
}
239
240
/* Table of all conditional affixes.  */
241
const aarch64_cond aarch64_conds[16] =
242
{
243
  {{"eq", "none"}, 0x0},
244
  {{"ne", "any"}, 0x1},
245
  {{"cs", "hs", "nlast"}, 0x2},
246
  {{"cc", "lo", "ul", "last"}, 0x3},
247
  {{"mi", "first"}, 0x4},
248
  {{"pl", "nfrst"}, 0x5},
249
  {{"vs"}, 0x6},
250
  {{"vc"}, 0x7},
251
  {{"hi", "pmore"}, 0x8},
252
  {{"ls", "plast"}, 0x9},
253
  {{"ge", "tcont"}, 0xa},
254
  {{"lt", "tstop"}, 0xb},
255
  {{"gt"}, 0xc},
256
  {{"le"}, 0xd},
257
  {{"al"}, 0xe},
258
  {{"nv"}, 0xf},
259
};
260
261
const aarch64_cond *
262
get_cond_from_value (aarch64_insn value)
263
73.2k
{
264
73.2k
  assert (value < 16);
265
73.2k
  return &aarch64_conds[(unsigned int) value];
266
73.2k
}
267
268
const aarch64_cond *
269
get_inverted_cond (const aarch64_cond *cond)
270
520
{
271
520
  return &aarch64_conds[cond->value ^ 0x1];
272
520
}
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
719k
{
316
719k
  if (extend_p)
317
124k
    return AARCH64_MOD_UXTB + value;
318
595k
  else
319
595k
    return AARCH64_MOD_LSL - value;
320
719k
}
321
322
bool
323
aarch64_extend_operator_p (enum aarch64_modifier_kind kind)
324
53.8k
{
325
53.8k
  return kind > AARCH64_MOD_LSL && kind <= AARCH64_MOD_SXTX;
326
53.8k
}
327
328
static inline bool
329
aarch64_shift_operator_p (enum aarch64_modifier_kind kind)
330
570k
{
331
570k
  return kind >= AARCH64_MOD_ROR && kind <= AARCH64_MOD_LSL;
332
570k
}
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.17M
{
433
3.17M
  return (low <= value) && (value <= high);
434
3.17M
}
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.15M
{
440
2.15M
  return (value % align) == 0;
441
2.15M
}
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.41M
{
447
1.41M
  assert (width < 32);
448
1.41M
  if (width < sizeof (value) * 8)
449
1.41M
    {
450
1.41M
      int64_t lim = (uint64_t) 1 << (width - 1);
451
1.41M
      if (value >= -lim && value < lim)
452
1.41M
  return true;
453
1.41M
    }
454
0
  return false;
455
1.41M
}
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.50M
{
461
2.50M
  assert (width < 32);
462
2.50M
  if (width < sizeof (value) * 8)
463
2.50M
    {
464
2.50M
      int64_t lim = (uint64_t) 1 << width;
465
2.50M
      if (value >= 0 && value < lim)
466
2.50M
  return true;
467
2.50M
    }
468
0
  return false;
469
2.50M
}
470
471
/* Return true if OPERAND is SP or WSP.  */
472
bool
473
aarch64_stack_pointer_p (const aarch64_opnd_info *operand)
474
168k
{
475
168k
  return ((aarch64_get_operand_class (operand->type)
476
168k
     == AARCH64_OPND_CLASS_INT_REG)
477
168k
    && operand_maybe_stack_pointer (aarch64_operands + operand->type)
478
109k
    && operand->reg.regno == 31);
479
168k
}
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.6M
{
581
12.6M
  return aarch64_opnd_qualifiers[qualifier].kind == OQK_OPD_VARIANT;
582
12.6M
}
583
584
static inline bool
585
qualifier_value_in_range_constraint_p (aarch64_opnd_qualifier_t qualifier)
586
4.57M
{
587
4.57M
  return aarch64_opnd_qualifiers[qualifier].kind == OQK_VALUE_IN_RANGE;
588
4.57M
}
589
590
const char*
591
aarch64_get_qualifier_name (aarch64_opnd_qualifier_t qualifier)
592
4.82M
{
593
4.82M
  return aarch64_opnd_qualifiers[qualifier].desc;
594
4.82M
}
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
9.07M
{
601
9.07M
  assert (operand_variant_qualifier_p (qualifier));
602
9.07M
  return aarch64_opnd_qualifiers[qualifier].data0;
603
9.07M
}
604
605
unsigned char
606
aarch64_get_qualifier_nelem (aarch64_opnd_qualifier_t qualifier)
607
114k
{
608
114k
  assert (operand_variant_qualifier_p (qualifier));
609
114k
  return aarch64_opnd_qualifiers[qualifier].data1;
610
114k
}
611
612
aarch64_insn
613
aarch64_get_qualifier_standard_value (aarch64_opnd_qualifier_t qualifier)
614
3.49M
{
615
3.49M
  assert (operand_variant_qualifier_p (qualifier));
616
3.49M
  return aarch64_opnd_qualifiers[qualifier].data2;
617
3.49M
}
618
619
static int
620
get_lower_bound (aarch64_opnd_qualifier_t qualifier)
621
499k
{
622
499k
  assert (qualifier_value_in_range_constraint_p (qualifier));
623
499k
  return aarch64_opnd_qualifiers[qualifier].data0;
624
499k
}
625
626
static int
627
get_upper_bound (aarch64_opnd_qualifier_t qualifier)
628
534k
{
629
534k
  assert (qualifier_value_in_range_constraint_p (qualifier));
630
534k
  return aarch64_opnd_qualifiers[qualifier].data1;
631
534k
}
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
593
{
677
593
  int i = 0;
678
593
  const enum aarch64_opnd *opnds = opcode->operands;
679
680
593
  if (opnds[0] == AARCH64_OPND_NIL)
681
0
    return false;
682
683
1.69k
  while (opnds[++i] != AARCH64_OPND_NIL)
684
1.43k
    if (opnds[i] == opnds[0])
685
341
      return true;
686
687
252
  return false;
688
593
}
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.5M
{
696
10.5M
  int i = 0;
697
10.5M
  const enum aarch64_opnd *opnds = opcode->operands;
698
36.3M
  while (opnds[i++] != AARCH64_OPND_NIL)
699
25.7M
    ;
700
10.5M
  --i;
701
10.5M
  assert (i >= 0 && i <= AARCH64_MAX_OPND_NUM);
702
10.5M
  return i;
703
10.5M
}
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.51M
{
736
9.51M
  int i, num_opnds, invalid, min_invalid;
737
9.51M
  const aarch64_opnd_qualifier_t *qualifiers;
738
739
9.51M
  num_opnds = aarch64_num_of_operands (inst->opcode);
740
9.51M
  if (num_opnds == 0)
741
113
    {
742
113
      DEBUG_TRACE ("SUCCEED: no operand");
743
113
      *invalid_count = 0;
744
113
      return 1;
745
113
    }
746
747
9.51M
  if (stop_at < 0 || stop_at >= num_opnds)
748
8.30M
    stop_at = num_opnds - 1;
749
750
  /* For each pattern.  */
751
9.51M
  min_invalid = num_opnds;
752
13.0M
  for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i, ++qualifiers_list)
753
13.0M
    {
754
13.0M
      int j;
755
13.0M
      qualifiers = *qualifiers_list;
756
757
      /* Start as positive.  */
758
13.0M
      invalid = 0;
759
760
13.0M
      DEBUG_TRACE ("%d", i);
761
#ifdef DEBUG_AARCH64
762
      if (debug_dump)
763
  dump_match_qualifiers (inst->operands, qualifiers);
764
#endif
765
766
      /* The first entry should be taken literally, even if it's an empty
767
   qualifier sequence.  In other positions an empty sequence acts as a
768
   terminator.  */
769
13.0M
      if (i > 0 && empty_qualifier_sequence_p (qualifiers))
770
74.2k
  break;
771
772
45.1M
      for (j = 0; j < num_opnds && j <= stop_at; ++j, ++qualifiers)
773
32.1M
  if (inst->operands[j].qualifier != *qualifiers
774
21.8M
       && inst->operands[j].qualifier != AARCH64_OPND_QLF_UNKNOWN)
775
5.04M
    invalid += 1;
776
777
13.0M
      if (min_invalid > invalid)
778
11.5M
  min_invalid = invalid;
779
780
      /* Qualifiers established.  */
781
13.0M
      if (min_invalid == 0)
782
9.43M
  break;
783
13.0M
    }
784
785
9.51M
  *invalid_count = min_invalid;
786
9.51M
  if (min_invalid == 0)
787
9.43M
    {
788
      /* Fill the result in *RET.  */
789
9.43M
      int j;
790
9.43M
      qualifiers = *qualifiers_list;
791
792
9.43M
      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.7M
      for (j = 0; j <= stop_at; ++j, ++qualifiers)
799
22.3M
  ret[j] = *qualifiers;
800
53.1M
      for (; j < AARCH64_MAX_OPND_NUM; ++j)
801
43.7M
  ret[j] = AARCH64_OPND_QLF_UNKNOWN;
802
803
9.43M
      DEBUG_TRACE ("SUCCESS");
804
9.43M
      return 1;
805
9.43M
    }
806
807
74.2k
  DEBUG_TRACE ("FAIL");
808
74.2k
  return 0;
809
9.51M
}
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.30M
{
826
8.30M
  int i;
827
8.30M
  aarch64_opnd_qualifier_seq_t qualifiers;
828
829
8.30M
  if (!aarch64_find_best_match (inst, inst->opcode->qualifiers_list, -1,
830
8.30M
        qualifiers, invalid_count))
831
44.4k
    {
832
44.4k
      DEBUG_TRACE ("matching FAIL");
833
44.4k
      return 0;
834
44.4k
    }
835
836
  /* Update the qualifiers.  */
837
8.25M
  if (update_p)
838
27.5M
    for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
839
27.5M
      {
840
27.5M
  if (inst->opcode->operands[i] == AARCH64_OPND_NIL)
841
8.25M
    break;
842
19.2M
  DEBUG_TRACE_IF (inst->operands[i].qualifier != qualifiers[i],
843
19.2M
      "update %s with %s for operand %d",
844
19.2M
      aarch64_get_qualifier_name (inst->operands[i].qualifier),
845
19.2M
      aarch64_get_qualifier_name (qualifiers[i]), i);
846
19.2M
  inst->operands[i].qualifier = qualifiers[i];
847
19.2M
      }
848
849
8.25M
  DEBUG_TRACE ("matching SUCCESS");
850
8.25M
  return 1;
851
8.30M
}
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
102k
{
863
102k
  int amount;
864
865
102k
  DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 ")", value, value);
866
867
102k
  if (is32)
868
17.1k
    {
869
      /* Allow all zeros or all ones in top 32-bits, so that
870
   32-bit constant expressions like ~0x80000000 are
871
   permitted.  */
872
17.1k
      if (value >> 32 != 0 && value >> 32 != 0xffffffff)
873
  /* Immediate out of range.  */
874
0
  return false;
875
17.1k
      value &= 0xffffffff;
876
17.1k
    }
877
878
  /* first, try movz then movn */
879
102k
  amount = -1;
880
102k
  if ((value & ((uint64_t) 0xffff << 0)) == value)
881
24.0k
    amount = 0;
882
78.2k
  else if ((value & ((uint64_t) 0xffff << 16)) == value)
883
11.3k
    amount = 16;
884
66.8k
  else if (!is32 && (value & ((uint64_t) 0xffff << 32)) == value)
885
27.8k
    amount = 32;
886
39.0k
  else if (!is32 && (value & ((uint64_t) 0xffff << 48)) == value)
887
5.79k
    amount = 48;
888
889
102k
  if (amount == -1)
890
33.2k
    {
891
33.2k
      DEBUG_TRACE ("exit false with 0x%" PRIx64 "(%" PRIi64 ")", value, value);
892
33.2k
      return false;
893
33.2k
    }
894
895
69.0k
  if (shift_amount != NULL)
896
0
    *shift_amount = amount;
897
898
69.0k
  DEBUG_TRACE ("exit true with amount %d", amount);
899
900
69.0k
  return true;
901
102k
}
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
352k
#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.15M
{
935
4.15M
  const simd_imm_encoding *imm1 = (const simd_imm_encoding *)i1;
936
4.15M
  const simd_imm_encoding *imm2 = (const simd_imm_encoding *)i2;
937
938
4.15M
  if (imm1->imm < imm2->imm)
939
2.07M
    return -1;
940
2.07M
  if (imm1->imm > imm2->imm)
941
1.71M
    return +1;
942
352k
  return 0;
943
2.07M
}
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
352k
{
1036
352k
  simd_imm_encoding imm_enc;
1037
352k
  const simd_imm_encoding *imm_encoding;
1038
352k
  static bool initialized = false;
1039
352k
  uint64_t upper;
1040
352k
  int i;
1041
1042
352k
  DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 "), esize: %d", value,
1043
352k
         value, esize);
1044
1045
352k
  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
352k
  upper = (uint64_t) -1 << (esize * 4) << (esize * 4);
1054
352k
  if ((value & ~upper) != value && (value | upper) != value)
1055
0
    return false;
1056
1057
  /* Replicate to a full 64-bit value.  */
1058
352k
  value &= ~upper;
1059
610k
  for (i = esize * 8; i < 64; i *= 2)
1060
258k
    value |= (value << i);
1061
1062
352k
  imm_enc.imm = value;
1063
352k
  imm_encoding = (const simd_imm_encoding *)
1064
352k
    bsearch(&imm_enc, simd_immediates, TOTAL_IMM_NB,
1065
352k
            sizeof(simd_immediates[0]), simd_imm_encoding_cmp);
1066
352k
  if (imm_encoding == NULL)
1067
0
    {
1068
0
      DEBUG_TRACE ("exit with false");
1069
0
      return false;
1070
0
    }
1071
352k
  if (encoding != NULL)
1072
0
    *encoding = imm_encoding->encoding;
1073
352k
  DEBUG_TRACE ("exit with true");
1074
352k
  return true;
1075
352k
}
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
773
{
1084
773
  int i, ret;
1085
773
  uint32_t byte;
1086
1087
773
  ret = 0;
1088
6.95k
  for (i = 0; i < 8; i++)
1089
6.18k
    {
1090
6.18k
      byte = (imm >> (8 * i)) & 0xff;
1091
6.18k
      if (byte == 0xff)
1092
3.51k
  ret |= 1 << i;
1093
2.66k
      else if (byte != 0x00)
1094
0
  return -1;
1095
6.18k
    }
1096
773
  return ret;
1097
773
}
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.66k
{
1117
3.66k
  if (mismatch_detail == NULL)
1118
3.66k
    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
48.4k
{
1150
48.4k
  if (mismatch_detail == NULL)
1151
48.4k
    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
788
{
1180
788
  if (mismatch_detail == NULL)
1181
788
    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
98.1k
{
1190
98.1k
  if (mismatch_detail == NULL)
1191
98.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
806
{
1222
806
  if (mismatch_detail == NULL)
1223
806
    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
48.2k
{
1252
48.2k
  if (mismatch_detail == NULL)
1253
48.2k
    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
91.9k
{
1267
91.9k
  if (!value_in_range_p (opnd->reglane.regno, min_regno, max_regno))
1268
0
    {
1269
0
      set_invalid_regno_error (mismatch_detail, idx, prefix, min_regno,
1270
0
             max_regno);
1271
0
      return false;
1272
0
    }
1273
91.9k
  if (!value_in_range_p (opnd->reglane.index, min_index, max_index))
1274
0
    {
1275
0
      set_elem_idx_out_of_range_error (mismatch_detail, idx, min_index,
1276
0
               max_index);
1277
0
      return false;
1278
0
    }
1279
91.9k
  return true;
1280
91.9k
}
1281
1282
/* Check that register list operand OPND has NUM_REGS registers and a
1283
   register stride of STRIDE.  */
1284
1285
static bool
1286
check_reglist (const aarch64_opnd_info *opnd,
1287
         aarch64_operand_error *mismatch_detail, int idx,
1288
         int num_regs, int stride)
1289
406k
{
1290
406k
  if (opnd->reglist.num_regs != num_regs)
1291
806
    {
1292
806
      set_reg_list_length_error (mismatch_detail, idx, num_regs);
1293
806
      return false;
1294
806
    }
1295
405k
  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
405k
  return true;
1301
405k
}
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.39M
{
1335
1.39M
  const aarch64_operand *operand = get_operand_from_code (type);
1336
1.39M
  uint8_t size = get_operand_fields_width (operand);
1337
1.39M
  bool unsigned_imm = operand_need_unsigned_offset (operand);
1338
1.39M
  bool (*value_fit_field) (int64_t, unsigned)
1339
1.39M
    = (unsigned_imm
1340
1.39M
      ? value_fit_unsigned_field_p
1341
1.39M
      : value_fit_signed_field_p);
1342
1343
1.39M
  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.39M
  return true;
1350
1.39M
}
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
20.5k
{
1436
20.5k
  unsigned num_bytes = 0; /* total number of bytes transferred.  */
1437
20.5k
  enum aarch64_operand_class opnd_class;
1438
20.5k
  enum aarch64_opnd type;
1439
1440
60.9k
  for (int i = 0; i < AARCH64_MAX_OPND_NUM; i++)
1441
60.9k
    {
1442
60.9k
      type = opnds[i].type;
1443
60.9k
      opnd_class = aarch64_operands[type].op_class;
1444
60.9k
      if (opnd_class == AARCH64_OPND_CLASS_ADDRESS)
1445
20.5k
  break;
1446
40.4k
      num_bytes += aarch64_get_qualifier_esize (opnds[i].qualifier);
1447
40.4k
    }
1448
20.5k
  return num_bytes;
1449
20.5k
}
1450
1451
1452
/* General constraint checking based on operand code.
1453
1454
   Return 1 if OPNDS[IDX] meets the general constraint of operand code TYPE
1455
   as the IDXth operand of opcode OPCODE.  Otherwise return 0.
1456
1457
   This function has to be called after the qualifiers for all operands
1458
   have been resolved.
1459
1460
   Mismatching error message is returned in *MISMATCH_DETAIL upon request,
1461
   i.e. when MISMATCH_DETAIL is non-NULL.  This avoids the generation
1462
   of error message during the disassembling where error message is not
1463
   wanted.  We avoid the dynamic construction of strings of error messages
1464
   here (i.e. in libopcodes), as it is costly and complicated; instead, we
1465
   use a combination of error code, static string and some integer data to
1466
   represent an error.  */
1467
1468
static bool
1469
operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
1470
          enum aarch64_opnd type,
1471
          const aarch64_opcode *opcode,
1472
          aarch64_operand_error *mismatch_detail)
1473
19.2M
{
1474
19.2M
  unsigned num, modifiers, shift;
1475
19.2M
  unsigned char size;
1476
19.2M
  int64_t imm, min_value, max_value;
1477
19.2M
  uint64_t uvalue, mask;
1478
19.2M
  const aarch64_opnd_info *opnd = opnds + idx;
1479
19.2M
  aarch64_opnd_qualifier_t qualifier = opnd->qualifier;
1480
19.2M
  int i;
1481
1482
19.2M
  assert (opcode->operands[idx] == opnd->type && opnd->type == type);
1483
1484
19.2M
  switch (aarch64_operands[type].op_class)
1485
19.2M
    {
1486
6.24M
    case AARCH64_OPND_CLASS_INT_REG:
1487
      /* Check for pair of xzr registers.  */
1488
6.24M
      if (type == AARCH64_OPND_PAIRREG_OR_XZR
1489
3.58k
    && opnds[idx - 1].reg.regno == 0x1f)
1490
1.72k
  {
1491
1.72k
    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.72k
  }
1499
      /* Check pair reg constraints for instructions taking a pair of
1500
   consecutively-numbered general-purpose registers.  */
1501
6.24M
      else if (type == AARCH64_OPND_PAIRREG
1502
6.24M
         || type == AARCH64_OPND_PAIRREG_OR_XZR)
1503
9.00k
  {
1504
9.00k
    assert (idx == 1 || idx == 2 || idx == 3 || idx == 5);
1505
9.00k
    if (opnds[idx - 1].reg.regno % 2 != 0)
1506
3.66k
      {
1507
3.66k
        set_syntax_error (mismatch_detail, idx - 1,
1508
3.66k
        _("reg pair must start from even reg"));
1509
3.66k
        return false;
1510
3.66k
      }
1511
5.34k
    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
5.34k
    break;
1518
5.34k
  }
1519
1520
      /* <Xt> may be optional in some IC and TLBI instructions.  */
1521
6.24M
      if (type == AARCH64_OPND_Rt_SYS)
1522
959
  {
1523
959
    assert (idx == 1 && (aarch64_get_operand_class (opnds[0].type)
1524
959
             == AARCH64_OPND_CLASS_SYSTEM));
1525
959
    if (!(opnds[1].present && aarch64_sys_ins_reg_tlbid_xt (opnds[0].sysins_op)))
1526
945
      {
1527
945
        if (opnds[1].present
1528
928
      && !aarch64_sys_ins_reg_has_xt (opnds[0].sysins_op))
1529
630
    {
1530
630
      set_other_error (mismatch_detail, idx, _("extraneous register"));
1531
630
      return false;
1532
630
    }
1533
315
        if (!opnds[1].present
1534
17
      && 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
315
     }
1540
959
  }
1541
6.23M
      break;
1542
1543
6.23M
    case AARCH64_OPND_CLASS_SVE_REG:
1544
1.68M
      switch (type)
1545
1.68M
  {
1546
5.02k
  case AARCH64_OPND_SVE_Zm3_INDEX:
1547
14.2k
  case AARCH64_OPND_SVE_Zm3_22_INDEX:
1548
14.5k
  case AARCH64_OPND_SVE_Zm3_19_INDEX:
1549
21.3k
  case AARCH64_OPND_SVE_Zm3_11_INDEX:
1550
25.5k
  case AARCH64_OPND_SVE_Zm3_10_INDEX:
1551
28.9k
  case AARCH64_OPND_SVE_Zm4_11_INDEX:
1552
34.4k
  case AARCH64_OPND_SVE_Zm4_INDEX:
1553
34.4k
    size = get_operand_fields_width (get_operand_from_code (type));
1554
34.4k
    shift = get_operand_specific_data (&aarch64_operands[type]);
1555
34.4k
    if (!check_reglane (opnd, mismatch_detail, idx,
1556
34.4k
            "z", 0, (1 << shift) - 1,
1557
34.4k
            0, (1u << (size - shift)) - 1))
1558
0
      return false;
1559
34.4k
    break;
1560
1561
34.4k
  case AARCH64_OPND_SVE_Zm1_23_INDEX:
1562
443
    size = get_operand_fields_width (get_operand_from_code (type));
1563
443
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31, 0, 1))
1564
0
      return 0;
1565
443
    break;
1566
1567
443
  case AARCH64_OPND_SME_Zn_INDEX2_19:
1568
1.39k
  case AARCH64_OPND_SVE_Zm2_22_INDEX:
1569
1.39k
    size = get_operand_fields_width (get_operand_from_code (type));
1570
1.39k
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31, 0, 3))
1571
0
      return 0;
1572
1.39k
    break;
1573
1574
2.22k
  case AARCH64_OPND_SVE_Zn_INDEX:
1575
2.22k
    size = aarch64_get_qualifier_esize (opnd->qualifier);
1576
2.22k
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31,
1577
2.22k
            0, 64 / size - 1))
1578
0
      return false;
1579
2.22k
    break;
1580
1581
2.22k
  case AARCH64_OPND_SVE_Zn_5_INDEX:
1582
420
    size = aarch64_get_qualifier_esize (opnd->qualifier);
1583
420
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31,
1584
420
            0, 16 / size - 1))
1585
0
      return false;
1586
420
    break;
1587
1588
420
  case AARCH64_OPND_SME_PNn3_INDEX1:
1589
157
  case AARCH64_OPND_SME_PNn3_INDEX2:
1590
157
    size = get_operand_field_width (get_operand_from_code (type), 0);
1591
157
    if (!check_reglane (opnd, mismatch_detail, idx, "pn", 8, 15,
1592
157
            0, (1 << size) - 1))
1593
0
      return false;
1594
157
    break;
1595
1596
986
  case AARCH64_OPND_SVE_Zm3_12_INDEX:
1597
1.27k
  case AARCH64_OPND_SME_Zn_INDEX1_16:
1598
1.57k
  case AARCH64_OPND_SME_Zn_INDEX2_15:
1599
2.14k
  case AARCH64_OPND_SME_Zn_INDEX2_16:
1600
2.39k
  case AARCH64_OPND_SME_Zn_INDEX3_14:
1601
2.63k
  case AARCH64_OPND_SME_Zn_INDEX3_15:
1602
2.87k
  case AARCH64_OPND_SME_Zn_INDEX4_14:
1603
2.95k
  case AARCH64_OPND_SVE_Zn0_INDEX:
1604
3.05k
  case AARCH64_OPND_SVE_Zn1_17_INDEX:
1605
3.18k
  case AARCH64_OPND_SVE_Zn2_18_INDEX:
1606
3.31k
  case AARCH64_OPND_SVE_Zn3_22_INDEX:
1607
3.40k
  case AARCH64_OPND_SVE_Zd0_INDEX:
1608
3.50k
  case AARCH64_OPND_SVE_Zd1_17_INDEX:
1609
3.58k
  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.06k
  case AARCH64_OPND_SME_Zm_INDEX2:
1619
3.21k
  case AARCH64_OPND_SME_Zm_INDEX2_3:
1620
5.13k
  case AARCH64_OPND_SME_Zm_INDEX3_1:
1621
7.58k
  case AARCH64_OPND_SME_Zm_INDEX3_2:
1622
8.37k
  case AARCH64_OPND_SME_Zm_INDEX3_3:
1623
13.1k
  case AARCH64_OPND_SME_Zm_INDEX3_10:
1624
15.3k
  case AARCH64_OPND_SME_Zm_INDEX4_1:
1625
16.2k
  case AARCH64_OPND_SME_Zm_INDEX4_2:
1626
34.9k
  case AARCH64_OPND_SME_Zm_INDEX4_3:
1627
40.7k
  case AARCH64_OPND_SME_Zm_INDEX4_10:
1628
40.7k
    size = get_operand_fields_width (get_operand_from_code (type)) - 5;
1629
40.7k
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 15,
1630
40.7k
            0, (1 << size) - 1))
1631
0
      return false;
1632
40.7k
    break;
1633
1634
40.7k
  case AARCH64_OPND_SME_Zk_INDEX:
1635
4.63k
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31, 0, 3))
1636
0
      return false;
1637
4.63k
    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.63k
    break;
1644
1645
8.75k
  case AARCH64_OPND_SME_Zm:
1646
8.80k
  case AARCH64_OPND_SME_Zm_17:
1647
8.80k
    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.80k
    break;
1653
1654
9.78k
  case AARCH64_OPND_SME_Zn_6_3:
1655
9.78k
    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
9.78k
    break;
1662
1663
9.78k
  case AARCH64_OPND_SME_Zm_17_3:
1664
9.58k
    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.58k
    break;
1671
1672
9.58k
  case AARCH64_OPND_SME_PnT_Wm_imm:
1673
8.64k
    size = aarch64_get_qualifier_esize (opnd->qualifier);
1674
8.64k
    max_value = 16 / size - 1;
1675
8.64k
    if (!check_za_access (opnd, mismatch_detail, idx,
1676
8.64k
        12, max_value, 1, 0, get_opcode_dependent_value (opcode)))
1677
0
      return false;
1678
8.64k
    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
367k
      switch (type)
1687
367k
  {
1688
895
  case AARCH64_OPND_SME_Pdx2:
1689
25.8k
  case AARCH64_OPND_SME_Zdnx2:
1690
32.8k
  case AARCH64_OPND_SME_Zdnx4:
1691
33.2k
  case AARCH64_OPND_SME_Znx2_6_3:
1692
33.9k
  case AARCH64_OPND_SME_Zmx2_17_3:
1693
36.6k
  case AARCH64_OPND_SME_Zmx2:
1694
37.1k
  case AARCH64_OPND_SME_Zmx4:
1695
55.0k
  case AARCH64_OPND_SME_Znx2:
1696
55.0k
  case AARCH64_OPND_SME_Znx2_BIT_INDEX:
1697
60.4k
  case AARCH64_OPND_SME_Znx4:
1698
60.4k
    num = get_operand_specific_data (&aarch64_operands[type]);
1699
60.4k
    if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
1700
0
      return false;
1701
60.4k
    if (((opnd->reglist.first_regno % num) != 0)
1702
60.4k
        || (type == AARCH64_OPND_SME_Znx2_6_3
1703
458
      && opnd->reglist.first_regno > 15)
1704
60.4k
        || (type == AARCH64_OPND_SME_Zmx2_17_3
1705
660
      && 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
60.4k
    break;
1712
1713
60.4k
  case AARCH64_OPND_SME_Ztx2_STRIDED:
1714
12.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
12.0k
    num = get_operand_specific_data (&aarch64_operands[type]);
1718
12.0k
    if (!check_reglist (opnd, mismatch_detail, idx, num, 16 / num))
1719
0
      return false;
1720
12.0k
    num = 16 | (opnd->reglist.stride - 1);
1721
12.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
12.0k
    break;
1728
1729
12.0k
  case AARCH64_OPND_SME_PdxN:
1730
13.1k
  case AARCH64_OPND_SVE_ZnxN:
1731
295k
  case AARCH64_OPND_SVE_ZtxN:
1732
295k
    num = get_opcode_dependent_value (opcode);
1733
295k
    if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
1734
0
      return false;
1735
295k
    break;
1736
1737
295k
  case AARCH64_OPND_SME_Zmx2_INDEX_22:
1738
196
    num = get_operand_specific_data (&aarch64_operands[type]);
1739
196
    if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
1740
0
        return false;
1741
196
    break;
1742
1743
196
  case AARCH64_OPND_SME_Zn7xN_UNTYPED:
1744
94
    num = get_opcode_dependent_value (opcode);
1745
94
    if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
1746
0
        return false;
1747
94
    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
94
    break;
1753
1754
94
  default:
1755
0
    abort ();
1756
367k
  }
1757
367k
      break;
1758
1759
367k
    case AARCH64_OPND_CLASS_ZA_ACCESS:
1760
194k
      switch (type)
1761
194k
  {
1762
1.32k
  case AARCH64_OPND_SME_ZA_HV_idx_src:
1763
77.8k
  case AARCH64_OPND_SME_ZA_HV_idx_dest:
1764
129k
  case AARCH64_OPND_SME_ZA_HV_idx_ldstr:
1765
129k
    size = aarch64_get_qualifier_esize (opnd->qualifier);
1766
129k
    max_value = 16 / size - 1;
1767
129k
    if (!check_za_access (opnd, mismatch_detail, idx, 12, max_value, 1,
1768
129k
        get_opcode_dependent_value (opcode),
1769
129k
        get_opcode_dependent_vg_status (opcode)))
1770
0
      return false;
1771
129k
    break;
1772
1773
129k
  case AARCH64_OPND_SME_ZA_array_off4:
1774
1.10k
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 15, 1,
1775
1.10k
        get_opcode_dependent_value (opcode),
1776
1.10k
        get_opcode_dependent_vg_status (opcode)))
1777
0
      return false;
1778
1.10k
    break;
1779
1780
10.2k
  case AARCH64_OPND_SME_ZA_array_off3_0:
1781
11.0k
  case AARCH64_OPND_SME_ZA_array_off3_5:
1782
11.0k
    if (!check_za_access (opnd, mismatch_detail, idx, 8, 7, 1,
1783
11.0k
        get_opcode_dependent_value (opcode),
1784
11.0k
        get_opcode_dependent_vg_status (opcode)))
1785
0
      return false;
1786
11.0k
    break;
1787
1788
11.0k
  case AARCH64_OPND_SME_ZA_array_off1x4:
1789
6.54k
    if (!check_za_access (opnd, mismatch_detail, idx, 8, 1, 4,
1790
6.54k
        get_opcode_dependent_value (opcode),
1791
6.54k
        get_opcode_dependent_vg_status (opcode)))
1792
0
      return false;
1793
6.54k
    break;
1794
1795
6.54k
  case AARCH64_OPND_SME_ZA_array_off2x2:
1796
5.32k
    if (!check_za_access (opnd, mismatch_detail, idx, 8, 3, 2,
1797
5.32k
        get_opcode_dependent_value (opcode),
1798
5.32k
        get_opcode_dependent_vg_status (opcode)))
1799
0
      return false;
1800
5.32k
    break;
1801
1802
6.93k
  case AARCH64_OPND_SME_ZA_array_off2x4:
1803
6.93k
    if (!check_za_access (opnd, mismatch_detail, idx, 8, 3, 4,
1804
6.93k
        get_opcode_dependent_value (opcode),
1805
6.93k
        get_opcode_dependent_vg_status (opcode)))
1806
0
      return false;
1807
6.93k
    break;
1808
1809
23.7k
  case AARCH64_OPND_SME_ZA_array_off3x2:
1810
23.7k
    if (!check_za_access (opnd, mismatch_detail, idx, 8, 7, 2,
1811
23.7k
        get_opcode_dependent_value (opcode),
1812
23.7k
        get_opcode_dependent_vg_status (opcode)))
1813
0
      return false;
1814
23.7k
    break;
1815
1816
23.7k
  case AARCH64_OPND_SME_ZA_array_vrsb_1:
1817
199
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 7, 2,
1818
199
        get_opcode_dependent_value (opcode),
1819
199
        get_opcode_dependent_vg_status (opcode)))
1820
0
      return false;
1821
199
    break;
1822
1823
199
  case AARCH64_OPND_SME_ZA_array_vrsh_1:
1824
49
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 3, 2,
1825
49
        get_opcode_dependent_value (opcode),
1826
49
        get_opcode_dependent_vg_status (opcode)))
1827
0
      return false;
1828
49
    break;
1829
1830
49
  case AARCH64_OPND_SME_ZA_array_vrss_1:
1831
48
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 1, 2,
1832
48
        get_opcode_dependent_value (opcode),
1833
48
        get_opcode_dependent_vg_status (opcode)))
1834
0
      return false;
1835
48
    break;
1836
1837
256
  case AARCH64_OPND_SME_ZA_array_vrsd_1:
1838
256
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 0, 2,
1839
256
        get_opcode_dependent_value (opcode),
1840
256
        get_opcode_dependent_vg_status (opcode)))
1841
0
      return false;
1842
256
    break;
1843
1844
256
  case AARCH64_OPND_SME_ZA_array_vrsb_2:
1845
204
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 3, 4,
1846
204
        get_opcode_dependent_value (opcode),
1847
204
        get_opcode_dependent_vg_status (opcode)))
1848
0
      return false;
1849
204
    break;
1850
1851
204
  case AARCH64_OPND_SME_ZA_array_vrsh_2:
1852
66
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 1, 4,
1853
66
        get_opcode_dependent_value (opcode),
1854
66
        get_opcode_dependent_vg_status (opcode)))
1855
0
      return false;
1856
66
    break;
1857
1858
792
  case AARCH64_OPND_SME_ZA_ARRAY4:
1859
792
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 15, 1,
1860
792
        get_opcode_dependent_value (opcode),
1861
792
        get_opcode_dependent_vg_status (opcode)))
1862
0
      return false;
1863
792
    break;
1864
1865
792
  case AARCH64_OPND_SME_ZA_array_vrss_2:
1866
619
  case AARCH64_OPND_SME_ZA_array_vrsd_2:
1867
619
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 0, 4,
1868
619
        get_opcode_dependent_value (opcode),
1869
619
        get_opcode_dependent_vg_status (opcode)))
1870
0
      return false;
1871
619
    break;
1872
1873
5.39k
  case AARCH64_OPND_SME_ZA_HV_idx_srcxN:
1874
7.59k
  case AARCH64_OPND_SME_ZA_HV_idx_destxN:
1875
7.59k
    size = aarch64_get_qualifier_esize (opnd->qualifier);
1876
7.59k
    num = get_opcode_dependent_value (opcode);
1877
7.59k
    max_value = 16 / num / size;
1878
7.59k
    if (max_value > 0)
1879
7.44k
      max_value -= 1;
1880
7.59k
    if (!check_za_access (opnd, mismatch_detail, idx, 12, max_value, num,
1881
7.59k
        0, get_opcode_dependent_value (opcode)))
1882
0
      return false;
1883
7.59k
    break;
1884
1885
7.59k
  default:
1886
0
    abort ();
1887
194k
  }
1888
194k
      break;
1889
1890
1.05M
    case AARCH64_OPND_CLASS_PRED_REG:
1891
1.05M
      switch (type)
1892
1.05M
  {
1893
1.96k
  case AARCH64_OPND_SME_PNd3:
1894
33.5k
  case AARCH64_OPND_SME_PNg3:
1895
33.5k
    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
33.5k
    break;
1901
1902
1.01M
  default:
1903
1.01M
    if (opnd->reg.regno >= 8
1904
72.8k
        && 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.01M
    break;
1910
1.05M
  }
1911
1.05M
      break;
1912
1913
1.05M
    case AARCH64_OPND_CLASS_COND:
1914
25.5k
      if (type == AARCH64_OPND_COND1
1915
520
    && (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.5k
      break;
1921
1922
3.34M
    case AARCH64_OPND_CLASS_ADDRESS:
1923
      /* Check writeback.  */
1924
3.34M
      switch (opcode->iclass)
1925
3.34M
  {
1926
248k
  case ldst_pos:
1927
334k
  case ldst_unscaled:
1928
485k
  case ldstnapair_offs:
1929
676k
  case ldstpair_off:
1930
689k
  case ldst_unpriv:
1931
689k
    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
689k
    break;
1938
689k
  case ldst_imm10:
1939
10.9k
    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.9k
    break;
1946
52.8k
  case ldst_imm9:
1947
308k
  case ldstpair_indexed:
1948
314k
  case asisdlsep:
1949
329k
  case asisdlsop:
1950
329k
    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
329k
    break;
1957
329k
  case rcpc3:
1958
26.3k
    if (opnd->addr.writeback)
1959
1.83k
      if ((type == AARCH64_OPND_RCPC3_ADDR_PREIND_WB
1960
264
     && !opnd->addr.preind)
1961
1.83k
    || (type == AARCH64_OPND_RCPC3_ADDR_POSTIND
1962
57
        && !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
26.3k
    break;
1970
2.28M
  default:
1971
2.28M
    assert (opnd->addr.writeback == 0);
1972
2.28M
    break;
1973
3.34M
  }
1974
3.34M
      switch (type)
1975
3.34M
  {
1976
572k
  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
572k
    size = aarch64_get_qualifier_esize (opnd->qualifier);
1982
572k
    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
572k
    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
572k
    break;
1994
572k
  case AARCH64_OPND_ADDR_OFFSET:
1995
144k
  case AARCH64_OPND_ADDR_SIMM9:
1996
    /* Unscaled signed 9 bits immediate offset.  */
1997
144k
    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
144k
    break;
2003
2004
144k
  case AARCH64_OPND_ADDR_SIMM10:
2005
    /* Scaled signed 10 bits immediate offset.  */
2006
10.9k
    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.9k
    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.9k
    break;
2017
2018
25.1k
  case AARCH64_OPND_ADDR_SIMM11:
2019
    /* Signed 11 bits immediate offset (multiple of 16).  */
2020
25.1k
    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.1k
    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.1k
    break;
2032
2033
25.1k
  case AARCH64_OPND_ADDR_SIMM13:
2034
    /* Signed 13 bits immediate offset (multiple of 16).  */
2035
7.85k
    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
7.85k
    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
7.85k
    break;
2047
2048
21.0k
  case AARCH64_OPND_SIMD_ADDR_POST:
2049
    /* AdvSIMD load/store multiple structures, post-index.  */
2050
21.0k
    assert (idx == 1);
2051
21.0k
    if (opnd->addr.offset.is_reg)
2052
17.8k
      {
2053
17.8k
        if (value_in_range_p (opnd->addr.offset.regno, 0, 30))
2054
17.8k
    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.8k
      }
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
723
    num_bytes = (is_ld1r ? 1 : prev->reglist.num_regs)
2072
723
      * aarch64_get_qualifier_esize (prev->qualifier);
2073
2.47k
        else
2074
2.47k
    num_bytes = prev->reglist.num_regs
2075
2.47k
      * aarch64_get_qualifier_esize (prev->qualifier)
2076
2.47k
      * 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
69.1k
  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
69.1k
    size = aarch64_get_qualifier_esize (opnd->qualifier);
2091
    /* It is either no shift or shift by the binary logarithm of SIZE.  */
2092
69.1k
    if (opnd->shifter.amount != 0
2093
40.2k
        && 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
69.1k
    switch (opnd->shifter.kind)
2102
69.1k
      {
2103
2.11k
      case AARCH64_MOD_UXTW:
2104
21.5k
      case AARCH64_MOD_LSL:
2105
24.0k
      case AARCH64_MOD_SXTW:
2106
29.4k
      case AARCH64_MOD_SXTX: break;
2107
39.6k
      default:
2108
39.6k
        set_other_error (mismatch_detail, idx,
2109
39.6k
             _("invalid extend/shift operator"));
2110
39.6k
        return false;
2111
69.1k
      }
2112
29.4k
    break;
2113
2114
248k
  case AARCH64_OPND_ADDR_UIMM12:
2115
248k
    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
248k
    size = aarch64_get_qualifier_esize (qualifier);
2120
248k
    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
248k
    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
248k
    break;
2132
2133
248k
  case AARCH64_OPND_ADDR_PCREL9:
2134
294k
  case AARCH64_OPND_ADDR_PCREL14:
2135
755k
  case AARCH64_OPND_ADDR_PCREL19:
2136
1.11M
  case AARCH64_OPND_ADDR_PCREL21:
2137
1.39M
  case AARCH64_OPND_ADDR_PCREL26:
2138
1.39M
    {
2139
1.39M
      imm = opnd->imm.value;
2140
1.39M
      if (operand_need_shift_by_two (get_operand_from_code (type)))
2141
1.03M
        {
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.03M
    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.03M
    imm >>= 2;
2152
1.03M
        }
2153
2154
1.39M
      if (!check_immediate_out_of_range (imm, type, mismatch_detail, idx))
2155
0
        return false;
2156
1.39M
    }
2157
1.39M
    break;
2158
2159
1.39M
  case AARCH64_OPND_SME_ADDR_RI_U4xVL:
2160
1.10k
    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
1.10k
    break;
2166
2167
66.3k
  case AARCH64_OPND_SVE_ADDR_RI_S4xVL:
2168
78.9k
  case AARCH64_OPND_SVE_ADDR_RI_S4x2xVL:
2169
82.9k
  case AARCH64_OPND_SVE_ADDR_RI_S4x3xVL:
2170
90.8k
  case AARCH64_OPND_SVE_ADDR_RI_S4x4xVL:
2171
90.8k
    min_value = -8;
2172
90.8k
    max_value = 7;
2173
99.9k
  sve_imm_offset_vl:
2174
99.9k
    assert (!opnd->addr.offset.is_reg);
2175
99.9k
    assert (opnd->addr.preind);
2176
99.9k
    num = 1 + get_operand_specific_data (&aarch64_operands[type]);
2177
99.9k
    min_value *= num;
2178
99.9k
    max_value *= num;
2179
99.9k
    if ((opnd->addr.offset.imm != 0 && !opnd->shifter.operator_present)
2180
99.9k
        || (opnd->shifter.operator_present
2181
93.9k
      && 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
99.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
99.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
99.9k
    break;
2199
2200
99.9k
  case AARCH64_OPND_SVE_ADDR_RI_S6xVL:
2201
3.07k
    min_value = -32;
2202
3.07k
    max_value = 31;
2203
3.07k
    goto sve_imm_offset_vl;
2204
2205
6.06k
  case AARCH64_OPND_SVE_ADDR_RI_S9xVL:
2206
6.06k
    min_value = -256;
2207
6.06k
    max_value = 255;
2208
6.06k
    goto sve_imm_offset_vl;
2209
2210
5.61k
  case AARCH64_OPND_SVE_ADDR_RI_U6:
2211
11.0k
  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
34.1k
  sve_imm_offset:
2217
34.1k
    assert (!opnd->addr.offset.is_reg);
2218
34.1k
    assert (opnd->addr.preind);
2219
34.1k
    num = 1 << get_operand_specific_data (&aarch64_operands[type]);
2220
34.1k
    min_value *= num;
2221
34.1k
    max_value *= num;
2222
34.1k
    if (opnd->shifter.operator_present
2223
34.1k
        || opnd->shifter.amount_present)
2224
0
      {
2225
0
        set_other_error (mismatch_detail, idx,
2226
0
             _("invalid addressing mode"));
2227
0
        return false;
2228
0
      }
2229
34.1k
    if (!value_in_range_p (opnd->addr.offset.imm, min_value, max_value))
2230
0
      {
2231
0
        set_offset_out_of_range_error (mismatch_detail, idx,
2232
0
               min_value, max_value);
2233
0
        return false;
2234
0
      }
2235
34.1k
    if (!value_aligned_p (opnd->addr.offset.imm, num))
2236
0
      {
2237
0
        set_unaligned_error (mismatch_detail, idx, num);
2238
0
        return false;
2239
0
      }
2240
34.1k
    break;
2241
2242
34.1k
  case AARCH64_OPND_SVE_ADDR_RI_S4x16:
2243
3.47k
  case AARCH64_OPND_SVE_ADDR_RI_S4x32:
2244
3.47k
    min_value = -8;
2245
3.47k
    max_value = 7;
2246
3.47k
    goto sve_imm_offset;
2247
2248
15.7k
  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.7k
    assert (opnd->addr.offset.is_reg);
2253
15.7k
    assert (opnd->addr.preind);
2254
15.7k
    assert ((aarch64_operands[type].flags & OPD_F_NO_ZR) == 0);
2255
15.7k
    assert (opnd->shifter.kind == AARCH64_MOD_LSL);
2256
15.7k
    assert (opnd->shifter.operator_present == 0);
2257
15.7k
    break;
2258
2259
15.7k
  case AARCH64_OPND_SVE_ADDR_RR:
2260
21.0k
  case AARCH64_OPND_SVE_ADDR_RR_LSL1:
2261
25.4k
  case AARCH64_OPND_SVE_ADDR_RR_LSL2:
2262
44.5k
  case AARCH64_OPND_SVE_ADDR_RR_LSL3:
2263
63.5k
  case AARCH64_OPND_SVE_ADDR_RR_LSL4:
2264
73.4k
  case AARCH64_OPND_SVE_ADDR_RM:
2265
77.5k
  case AARCH64_OPND_SVE_ADDR_RM_LSL1:
2266
81.9k
  case AARCH64_OPND_SVE_ADDR_RM_LSL2:
2267
85.6k
  case AARCH64_OPND_SVE_ADDR_RM_LSL3:
2268
85.6k
  case AARCH64_OPND_SVE_ADDR_RM_LSL4:
2269
102k
  case AARCH64_OPND_SVE_ADDR_RX:
2270
112k
  case AARCH64_OPND_SVE_ADDR_RX_LSL1:
2271
124k
  case AARCH64_OPND_SVE_ADDR_RX_LSL2:
2272
129k
  case AARCH64_OPND_SVE_ADDR_RX_LSL3:
2273
134k
  case AARCH64_OPND_SVE_ADDR_RX_LSL4:
2274
160k
  case AARCH64_OPND_SVE_ADDR_RZ:
2275
163k
  case AARCH64_OPND_SVE_ADDR_RZ_LSL1:
2276
166k
  case AARCH64_OPND_SVE_ADDR_RZ_LSL2:
2277
168k
  case AARCH64_OPND_SVE_ADDR_RZ_LSL3:
2278
168k
    modifiers = 1 << AARCH64_MOD_LSL;
2279
241k
  sve_rr_operand:
2280
241k
    assert (opnd->addr.offset.is_reg);
2281
241k
    assert (opnd->addr.preind);
2282
241k
    if ((aarch64_operands[type].flags & OPD_F_NO_ZR) != 0
2283
49.1k
        && 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
241k
    if (((1 << opnd->shifter.kind) & modifiers) == 0
2290
241k
        || (opnd->shifter.amount
2291
241k
      != 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
241k
    break;
2298
2299
241k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW_14:
2300
46.1k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW_22:
2301
47.9k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW1_14:
2302
56.5k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW1_22:
2303
57.7k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW2_14:
2304
64.3k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW2_22:
2305
65.3k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW3_14:
2306
72.7k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW3_22:
2307
72.7k
    modifiers = (1 << AARCH64_MOD_SXTW) | (1 << AARCH64_MOD_UXTW);
2308
72.7k
    goto sve_rr_operand;
2309
2310
5.32k
  case AARCH64_OPND_SVE_ADDR_ZI_U5:
2311
11.5k
  case AARCH64_OPND_SVE_ADDR_ZI_U5x2:
2312
14.5k
  case AARCH64_OPND_SVE_ADDR_ZI_U5x4:
2313
16.1k
  case AARCH64_OPND_SVE_ADDR_ZI_U5x8:
2314
16.1k
    min_value = 0;
2315
16.1k
    max_value = 31;
2316
16.1k
    goto sve_imm_offset;
2317
2318
1.05k
  case AARCH64_OPND_SVE_ADDR_ZZ_LSL:
2319
1.05k
    modifiers = 1 << AARCH64_MOD_LSL;
2320
2.25k
  sve_zz_operand:
2321
2.25k
    assert (opnd->addr.offset.is_reg);
2322
2.25k
    assert (opnd->addr.preind);
2323
2.25k
    if (((1 << opnd->shifter.kind) & modifiers) == 0
2324
2.25k
        || opnd->shifter.amount < 0
2325
2.25k
        || 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.25k
    break;
2332
2333
2.25k
  case AARCH64_OPND_SVE_ADDR_ZZ_SXTW:
2334
344
    modifiers = (1 << AARCH64_MOD_SXTW);
2335
344
    goto sve_zz_operand;
2336
2337
858
  case AARCH64_OPND_SVE_ADDR_ZZ_UXTW:
2338
858
    modifiers = 1 << AARCH64_MOD_UXTW;
2339
858
    goto sve_zz_operand;
2340
2341
17.3k
  case AARCH64_OPND_RCPC3_ADDR_OPT_PREIND_WB:
2342
18.3k
  case AARCH64_OPND_RCPC3_ADDR_OPT_POSTIND:
2343
18.6k
  case AARCH64_OPND_RCPC3_ADDR_PREIND_WB:
2344
18.6k
  case AARCH64_OPND_RCPC3_ADDR_POSTIND:
2345
18.6k
    {
2346
18.6k
      int num_bytes = calc_ldst_datasize (opnds);
2347
18.6k
      int abs_offset = (type == AARCH64_OPND_RCPC3_ADDR_OPT_PREIND_WB
2348
1.31k
            || type == AARCH64_OPND_RCPC3_ADDR_PREIND_WB)
2349
18.6k
        ? opnd->addr.offset.imm * -1
2350
18.6k
        : opnd->addr.offset.imm;
2351
18.6k
      if ((int) num_bytes != abs_offset
2352
16.8k
    && 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
18.6k
    }
2359
18.6k
    break;
2360
2361
18.6k
  case AARCH64_OPND_RCPC3_ADDR_OFFSET:
2362
7.60k
    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
436k
  default:
2369
436k
    break;
2370
3.34M
  }
2371
3.28M
      break;
2372
2373
3.28M
    case AARCH64_OPND_CLASS_SIMD_REGLIST:
2374
59.9k
      if (type == AARCH64_OPND_LEt)
2375
21.7k
  {
2376
    /* Get the upper bound for the element index.  */
2377
21.7k
    num = 16 / aarch64_get_qualifier_esize (qualifier) - 1;
2378
21.7k
    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
21.7k
  }
2384
      /* The opcode dependent area stores the number of elements in
2385
   each structure to be loaded/stored.  */
2386
59.9k
      num = get_opcode_dependent_value (opcode);
2387
59.9k
      switch (type)
2388
59.9k
  {
2389
3.83k
  case AARCH64_OPND_LVn_LUT:
2390
3.83k
    if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
2391
0
      return 0;
2392
3.83k
    break;
2393
15.2k
  case AARCH64_OPND_LVt:
2394
15.2k
    assert (num >= 1 && num <= 4);
2395
    /* Unless LD1/ST1, the number of registers should be equal to that
2396
       of the structure elements.  */
2397
15.2k
    if (num != 1 && !check_reglist (opnd, mismatch_detail, idx, num, 1))
2398
806
      return false;
2399
14.3k
    break;
2400
14.3k
  case AARCH64_OPND_LVt_AL:
2401
23.9k
  case AARCH64_OPND_LEt:
2402
23.9k
    assert (num >= 1 && num <= 4);
2403
    /* The number of registers should be equal to that of the structure
2404
       elements.  */
2405
23.9k
    if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
2406
0
      return false;
2407
23.9k
    break;
2408
23.9k
  default:
2409
16.9k
    break;
2410
59.9k
  }
2411
59.0k
      if (opnd->reglist.stride != 1)
2412
0
  {
2413
0
    set_reg_list_stride_error (mismatch_detail, idx, 1);
2414
0
    return false;
2415
0
  }
2416
59.0k
      break;
2417
2418
3.54M
    case AARCH64_OPND_CLASS_IMMEDIATE:
2419
      /* Constraint check on immediate operand.  */
2420
3.54M
      imm = opnd->imm.value;
2421
      /* E.g. imm_0_31 constrains value to be 0..31.  */
2422
3.54M
      if (qualifier_value_in_range_constraint_p (qualifier)
2423
451k
    && !value_in_range_p (imm, get_lower_bound (qualifier),
2424
451k
        get_upper_bound (qualifier)))
2425
48.4k
  {
2426
48.4k
    set_imm_out_of_range_error (mismatch_detail, idx,
2427
48.4k
              get_lower_bound (qualifier),
2428
48.4k
              get_upper_bound (qualifier));
2429
48.4k
    return false;
2430
48.4k
  }
2431
2432
3.49M
      switch (type)
2433
3.49M
  {
2434
448k
  case AARCH64_OPND_AIMM:
2435
448k
    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
448k
    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
448k
    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
448k
    break;
2454
2455
448k
  case AARCH64_OPND_HALF:
2456
115k
    assert (idx == 1 && opnds[0].type == AARCH64_OPND_Rd);
2457
115k
    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
115k
    size = aarch64_get_qualifier_esize (opnds[0].qualifier);
2464
115k
    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
115k
    if (!value_in_range_p (opnd->shifter.amount, 0, size * 8 - 16))
2471
19.1k
      {
2472
19.1k
        set_sft_amount_out_of_range_error (mismatch_detail, idx,
2473
19.1k
             0, size * 8 - 16);
2474
19.1k
        return false;
2475
19.1k
      }
2476
96.1k
    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
96.1k
    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
96.1k
    break;
2489
2490
96.1k
  case AARCH64_OPND_IMM_MOV:
2491
69.3k
      {
2492
69.3k
        int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
2493
69.3k
        imm = opnd->imm.value;
2494
69.3k
        assert (idx == 1);
2495
69.3k
        switch (opcode->op)
2496
69.3k
    {
2497
32.0k
    case OP_MOV_IMM_WIDEN:
2498
32.0k
      imm = ~imm;
2499
      /* Fall through.  */
2500
68.4k
    case OP_MOV_IMM_WIDE:
2501
68.4k
      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
68.4k
      break;
2508
68.4k
    case OP_MOV_IMM_LOG:
2509
903
      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
903
      break;
2516
903
    default:
2517
0
      assert (0);
2518
0
      return false;
2519
69.3k
    }
2520
69.3k
      }
2521
69.3k
    break;
2522
2523
69.3k
  case AARCH64_OPND_NZCV:
2524
12.0k
  case AARCH64_OPND_CCMP_IMM:
2525
13.1k
  case AARCH64_OPND_EXCEPTION:
2526
1.90M
  case AARCH64_OPND_UNDEFINED:
2527
1.90M
  case AARCH64_OPND_TME_UIMM16:
2528
1.90M
  case AARCH64_OPND_UIMM4:
2529
1.91M
  case AARCH64_OPND_UIMM4_ADDG:
2530
1.91M
  case AARCH64_OPND_UIMM7:
2531
1.92M
  case AARCH64_OPND_UIMM3_OP1:
2532
1.93M
  case AARCH64_OPND_UIMM3_OP2:
2533
1.93M
  case AARCH64_OPND_SVE_UIMM3:
2534
1.95M
  case AARCH64_OPND_SVE_UIMM7:
2535
1.95M
  case AARCH64_OPND_SVE_UIMM8:
2536
1.95M
  case AARCH64_OPND_SVE_UIMM4:
2537
1.96M
  case AARCH64_OPND_SVE_UIMM8_53:
2538
1.96M
  case AARCH64_OPND_CSSC_UIMM8:
2539
1.96M
    size = get_operand_fields_width (get_operand_from_code (type));
2540
1.96M
    assert (size < 32);
2541
1.96M
    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.96M
    break;
2548
2549
1.96M
  case AARCH64_OPND_UIMM10:
2550
    /* Scaled unsigned 10 bits immediate offset.  */
2551
4.43k
    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.43k
    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.43k
    break;
2563
2564
13.7k
  case AARCH64_OPND_SIMM5:
2565
14.2k
  case AARCH64_OPND_SVE_SIMM5:
2566
14.6k
  case AARCH64_OPND_SVE_SIMM5B:
2567
15.4k
  case AARCH64_OPND_SVE_SIMM6:
2568
16.1k
  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.6k
  case AARCH64_OPND_WIDTH:
2582
34.6k
    assert (idx > 1 && opnds[idx-1].type == AARCH64_OPND_IMM
2583
34.6k
      && opnds[0].type == AARCH64_OPND_Rd);
2584
34.6k
    size = get_upper_bound (qualifier);
2585
34.6k
    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.6k
    break;
2593
2594
306k
  case AARCH64_OPND_LIMM:
2595
348k
  case AARCH64_OPND_SVE_LIMM:
2596
348k
    {
2597
348k
      int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
2598
348k
      uint64_t uimm = opnd->imm.value;
2599
348k
      if (opcode->op == OP_BIC)
2600
0
        uimm = ~uimm;
2601
348k
      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
348k
    }
2608
348k
    break;
2609
2610
348k
  case AARCH64_OPND_IMM0:
2611
620
  case AARCH64_OPND_FPIMM0:
2612
620
    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
620
    break;
2619
2620
849
  case AARCH64_OPND_IMM_ROT1:
2621
17.7k
  case AARCH64_OPND_IMM_ROT2:
2622
26.7k
  case AARCH64_OPND_SVE_IMM_ROT2:
2623
26.7k
    if (opnd->imm.value != 0
2624
19.6k
        && opnd->imm.value != 90
2625
12.7k
        && opnd->imm.value != 180
2626
8.46k
        && 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.7k
    break;
2633
2634
26.7k
  case AARCH64_OPND_IMM_ROT3:
2635
1.20k
  case AARCH64_OPND_SVE_IMM_ROT1:
2636
1.55k
  case AARCH64_OPND_SVE_IMM_ROT3:
2637
1.55k
    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.55k
    break;
2644
2645
1.55k
  case AARCH64_OPND_SHLL_IMM:
2646
157
    assert (idx == 2);
2647
157
    size = 8 * aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
2648
157
    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
157
    break;
2655
2656
9.26k
  case AARCH64_OPND_IMM_VLSL:
2657
9.26k
    size = aarch64_get_qualifier_esize (qualifier);
2658
9.26k
    if (!value_in_range_p (opnd->imm.value, 0, size * 8 - 1))
2659
0
      {
2660
0
        set_imm_out_of_range_error (mismatch_detail, idx, 0,
2661
0
            size * 8 - 1);
2662
0
        return false;
2663
0
      }
2664
9.26k
    break;
2665
2666
14.6k
  case AARCH64_OPND_IMM_VLSR:
2667
14.6k
    size = aarch64_get_qualifier_esize (qualifier);
2668
14.6k
    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.6k
    break;
2674
2675
14.6k
  case AARCH64_OPND_SIMD_IMM:
2676
4.16k
  case AARCH64_OPND_SIMD_IMM_SFT:
2677
    /* Qualifier check.  */
2678
4.16k
    switch (qualifier)
2679
4.16k
      {
2680
3.01k
      case AARCH64_OPND_QLF_LSL:
2681
3.01k
        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.01k
        break;
2688
3.01k
      case AARCH64_OPND_QLF_MSL:
2689
372
        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
372
        break;
2696
773
      case AARCH64_OPND_QLF_NIL:
2697
773
        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
773
        break;
2704
773
      default:
2705
0
        assert (0);
2706
0
        return false;
2707
4.16k
      }
2708
    /* Is the immediate valid?  */
2709
4.16k
    assert (idx == 1);
2710
4.16k
    if (aarch64_get_qualifier_esize (opnds[0].qualifier) != 8)
2711
3.38k
      {
2712
        /* uimm8 or simm8 */
2713
3.38k
        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.38k
      }
2719
773
    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.16k
    switch (opnd->shifter.kind)
2730
4.16k
      {
2731
3.01k
      case AARCH64_MOD_LSL:
2732
3.01k
        size = aarch64_get_qualifier_esize (opnds[0].qualifier);
2733
3.01k
        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.01k
        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.01k
        break;
2745
3.01k
      case AARCH64_MOD_MSL:
2746
        /* Only 8 and 16 are valid shift amount.  */
2747
372
        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
372
        break;
2754
773
      default:
2755
773
        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
773
        break;
2762
4.16k
      }
2763
4.16k
    break;
2764
2765
4.16k
  case AARCH64_OPND_FPIMM:
2766
2.31k
  case AARCH64_OPND_SIMD_FPIMM:
2767
3.97k
  case AARCH64_OPND_SVE_FPIMM8:
2768
3.97k
    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
3.97k
    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
3.97k
    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
3.97k
    break;
2791
2792
3.97k
  case AARCH64_OPND_SVE_AIMM:
2793
2.88k
    min_value = 0;
2794
19.6k
  sve_aimm:
2795
19.6k
    assert (opnd->shifter.kind == AARCH64_MOD_LSL);
2796
19.6k
    size = aarch64_get_qualifier_esize (opnds[0].qualifier);
2797
19.6k
    mask = ~((uint64_t) -1 << (size * 4) << (size * 4));
2798
19.6k
    uvalue = opnd->imm.value;
2799
19.6k
    shift = opnd->shifter.amount;
2800
19.6k
    if (size == 1)
2801
4.52k
      {
2802
4.52k
        if (shift != 0)
2803
131
    {
2804
131
      set_other_error (mismatch_detail, idx,
2805
131
           _("no shift amount allowed for"
2806
131
             " 8-bit constants"));
2807
131
      return false;
2808
131
    }
2809
4.52k
      }
2810
15.1k
    else
2811
15.1k
      {
2812
15.1k
        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.1k
        if (shift == 0 && (uvalue & 0xff) == 0)
2819
5.77k
    {
2820
5.77k
      shift = 8;
2821
5.77k
      uvalue = (int64_t) uvalue / 256;
2822
5.77k
    }
2823
15.1k
      }
2824
19.5k
    mask >>= shift;
2825
19.5k
    if ((uvalue & mask) != uvalue && (uvalue | ~mask) != uvalue)
2826
1.67k
      {
2827
1.67k
        set_other_error (mismatch_detail, idx,
2828
1.67k
             _("immediate too big for element size"));
2829
1.67k
        return false;
2830
1.67k
      }
2831
17.8k
    uvalue = (uvalue - min_value) & mask;
2832
17.8k
    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
17.8k
    break;
2839
2840
17.8k
  case AARCH64_OPND_SVE_ASIMM:
2841
16.7k
    min_value = -128;
2842
16.7k
    goto sve_aimm;
2843
2844
97
  case AARCH64_OPND_SVE_I1_HALF_ONE:
2845
97
    assert (opnd->imm.is_fp);
2846
97
    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
97
    break;
2853
2854
268
  case AARCH64_OPND_SVE_I1_HALF_TWO:
2855
268
    assert (opnd->imm.is_fp);
2856
268
    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
268
    break;
2863
2864
1.19k
  case AARCH64_OPND_SVE_I1_ZERO_ONE:
2865
1.19k
    assert (opnd->imm.is_fp);
2866
1.19k
    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.19k
    break;
2873
2874
1.19k
  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.47k
  case AARCH64_OPND_SVE_LIMM_MOV:
2888
3.47k
    {
2889
3.47k
      int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
2890
3.47k
      uint64_t uimm = opnd->imm.value;
2891
3.47k
      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.47k
      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.47k
    }
2904
3.47k
    break;
2905
2906
7.39k
  case AARCH64_OPND_SVE_PATTERN_SCALED:
2907
7.39k
    assert (opnd->shifter.kind == AARCH64_MOD_MUL);
2908
7.39k
    if (!value_in_range_p (opnd->shifter.amount, 1, 16))
2909
0
      {
2910
0
        set_multiplier_out_of_range_error (mismatch_detail, idx, 1, 16);
2911
0
        return false;
2912
0
      }
2913
7.39k
    break;
2914
2915
7.39k
  case AARCH64_OPND_SVE_SHLIMM_PRED:
2916
2.10k
  case AARCH64_OPND_SVE_SHLIMM_UNPRED:
2917
2.81k
  case AARCH64_OPND_SVE_SHLIMM_UNPRED_22:
2918
2.81k
    size = aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
2919
2.81k
    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
2.81k
    break;
2926
2927
2.81k
  case AARCH64_OPND_SME_SHRIMM3:
2928
390
  case AARCH64_OPND_SME_SHRIMM4:
2929
390
    size = 1 << get_operand_fields_width (get_operand_from_code (type));
2930
390
    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
390
    break;
2936
2937
390
  case AARCH64_OPND_SME_SHRIMM5:
2938
1.89k
  case AARCH64_OPND_SVE_SHRIMM_PRED:
2939
4.31k
  case AARCH64_OPND_SVE_SHRIMM_UNPRED:
2940
9.66k
  case AARCH64_OPND_SVE_SHRIMM_UNPRED_22:
2941
9.66k
    num = (type == AARCH64_OPND_SVE_SHRIMM_UNPRED_22) ? 2 : 1;
2942
9.66k
    size = aarch64_get_qualifier_esize (opnds[idx - num].qualifier);
2943
9.66k
    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.66k
    break;
2949
2950
9.66k
  case AARCH64_OPND_SME_ZT0_INDEX:
2951
92
    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
92
    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
92
    break;
2963
2964
129
  case AARCH64_OPND_SME_ZT0_INDEX_MUL_VL:
2965
129
    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
129
    break;
2971
2972
385k
  default:
2973
385k
    break;
2974
3.49M
  }
2975
3.47M
      break;
2976
2977
3.47M
    case AARCH64_OPND_CLASS_SYSTEM:
2978
68.3k
      switch (type)
2979
68.3k
  {
2980
261
  case AARCH64_OPND_PSTATEFIELD:
2981
976
    for (i = 0; aarch64_pstatefields[i].name; ++i)
2982
976
      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
24
      {
2989
24
        set_imm_out_of_range_error (mismatch_detail, 1, 0, max_value);
2990
24
        return false;
2991
24
      }
2992
237
    break;
2993
47.9k
  case AARCH64_OPND_PRFOP:
2994
47.9k
    if (opcode->iclass == ldst_regoff && opnd->prfop->value >= 24)
2995
1.01k
      {
2996
1.01k
        set_other_error (mismatch_detail, idx,
2997
1.01k
             _("the register-index form of PRFM does"
2998
1.01k
         " not accept opcodes in the range 24-31"));
2999
1.01k
        return false;
3000
1.01k
      }
3001
46.9k
    break;
3002
46.9k
  default:
3003
20.0k
    break;
3004
68.3k
  }
3005
67.2k
      break;
3006
3007
105k
    case AARCH64_OPND_CLASS_SIMD_ELEMENT:
3008
      /* Get the upper bound for the element index.  */
3009
105k
      if (opcode->op == OP_FCMLA_ELEM)
3010
  /* FCMLA index range depends on the vector size of other operands
3011
     and is halfed because complex numbers take two elements.  */
3012
8.23k
  num = aarch64_get_qualifier_nelem (opnds[0].qualifier)
3013
8.23k
        * aarch64_get_qualifier_esize (opnds[0].qualifier) / 2;
3014
96.8k
      else if (opcode->iclass == lut)
3015
3.83k
  {
3016
3.83k
    size = get_operand_fields_width (get_operand_from_code (type)) - 5;
3017
3.83k
    if (!check_reglane (opnd, mismatch_detail, idx, "v", 0, 31,
3018
3.83k
            0, (1 << size) - 1))
3019
0
      return 0;
3020
3.83k
    break;
3021
3.83k
  }
3022
93.0k
      else
3023
93.0k
  num = 16;
3024
101k
      num = num / aarch64_get_qualifier_esize (qualifier) - 1;
3025
101k
      assert (aarch64_get_qualifier_nelem (qualifier) == 1);
3026
3027
      /* Index out-of-range.  */
3028
101k
      if (!value_in_range_p (opnd->reglane.index, 0, num))
3029
788
  {
3030
788
    set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, num);
3031
788
    return false;
3032
788
  }
3033
      /* SMLAL<Q> <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>].
3034
   <Vm> Is the vector register (V0-V31) or (V0-V15), whose
3035
   number is encoded in "size:M:Rm":
3036
   size <Vm>
3037
   00   RESERVED
3038
   01   0:Rm
3039
   10   M:Rm
3040
   11   RESERVED  */
3041
100k
      if (type == AARCH64_OPND_Em16
3042
48.5k
    && (qualifier == AARCH64_OPND_QLF_S_H
3043
9.44k
        || qualifier == AARCH64_OPND_QLF_S_2B)
3044
41.8k
    && !value_in_range_p (opnd->reglane.regno, 0, 15))
3045
0
  {
3046
0
    set_regno_out_of_range_error (mismatch_detail, idx, 0, 15);
3047
0
    return false;
3048
0
  }
3049
100k
      if (type == AARCH64_OPND_Em8
3050
3.64k
    && !value_in_range_p (opnd->reglane.regno, 0, 7))
3051
0
  {
3052
0
    set_regno_out_of_range_error (mismatch_detail, idx, 0, 7);
3053
0
    return 0;
3054
0
  }
3055
100k
      break;
3056
3057
625k
    case AARCH64_OPND_CLASS_MODIFIED_REG:
3058
625k
      assert (idx == 1 || idx == 2);
3059
625k
      switch (type)
3060
625k
  {
3061
53.8k
  case AARCH64_OPND_Rm_EXT:
3062
53.8k
    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
53.8k
    if (!aarch64_stack_pointer_p (opnds + 0)
3074
52.5k
        && (idx != 2 || !aarch64_stack_pointer_p (opnds + 1)))
3075
50.3k
      {
3076
50.3k
        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
50.3k
        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
50.3k
      }
3089
53.8k
    assert (opnd->shifter.operator_present  /* Default to LSL.  */
3090
53.8k
      || opnd->shifter.kind == AARCH64_MOD_LSL);
3091
53.8k
    if (!value_in_range_p (opnd->shifter.amount, 0, 4))
3092
9.09k
      {
3093
9.09k
        set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, 4);
3094
9.09k
        return false;
3095
9.09k
      }
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
44.7k
    if (qualifier == AARCH64_OPND_QLF_X
3102
4.27k
        && opnd->shifter.kind != AARCH64_MOD_LSL
3103
4.27k
        && opnd->shifter.kind != AARCH64_MOD_UXTX
3104
2.10k
        && 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
44.7k
    break;
3110
3111
570k
  case AARCH64_OPND_Rm_SFT:
3112
    /* ROR is not available to the shifted register operand in
3113
       arithmetic instructions.  */
3114
570k
    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
570k
    if (opnd->shifter.kind == AARCH64_MOD_ROR
3121
98.1k
        && 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
570k
    num = qualifier == AARCH64_OPND_QLF_W ? 31 : 63;
3128
570k
    if (!value_in_range_p (opnd->shifter.amount, 0, num))
3129
69.9k
      {
3130
69.9k
        set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, num);
3131
69.9k
        return false;
3132
69.9k
      }
3133
500k
    break;
3134
3135
500k
  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
929
    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
929
    break;
3145
3146
929
  default:
3147
0
    break;
3148
625k
  }
3149
546k
      break;
3150
3151
1.88M
    default:
3152
1.88M
      break;
3153
19.2M
    }
3154
3155
18.9M
  return true;
3156
19.2M
}
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.30M
{
3173
8.30M
  int i;
3174
3175
8.30M
  DEBUG_TRACE ("enter");
3176
3177
8.30M
  i = inst->opcode->tied_operand;
3178
3179
8.30M
  if (i > 0)
3180
88.4k
    {
3181
      /* Check for tied_operands with specific opcode iclass.  */
3182
88.4k
      switch (inst->opcode->iclass)
3183
88.4k
        {
3184
        /* For SME LDR and STR instructions #imm must have the same numerical
3185
           value for both operands.
3186
        */
3187
1.04k
        case sme_ldr:
3188
1.10k
        case sme_str:
3189
1.10k
          assert (inst->operands[0].type == AARCH64_OPND_SME_ZA_array_off4);
3190
1.10k
          assert (inst->operands[1].type == AARCH64_OPND_SME_ADDR_RI_U4xVL);
3191
1.10k
          if (inst->operands[0].indexed_za.index.imm
3192
1.10k
              != 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
1.10k
          break;
3202
3203
87.3k
        default:
3204
87.3k
    {
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
87.3k
      enum aarch64_operand_class op_class
3212
87.3k
         = aarch64_get_operand_class (inst->operands[0].type);
3213
87.3k
      assert (aarch64_get_operand_class (inst->operands[i].type)
3214
87.3k
        == op_class);
3215
87.3k
      if (op_class == AARCH64_OPND_CLASS_SVE_REGLIST
3216
87.3k
    ? ((inst->operands[0].reglist.first_regno
3217
371
        != inst->operands[i].reglist.first_regno)
3218
371
       || (inst->operands[0].reglist.num_regs
3219
371
           != inst->operands[i].reglist.num_regs)
3220
371
       || (inst->operands[0].reglist.stride
3221
371
           != inst->operands[i].reglist.stride))
3222
87.3k
    : (inst->operands[0].reg.regno
3223
86.9k
       != 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
87.3k
      break;
3234
87.3k
    }
3235
88.4k
        }
3236
88.4k
    }
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.30M
  int invalid_count;
3249
8.30M
  if (match_operands_qualifier (inst, true /* update_p */,
3250
8.30M
        &invalid_count) == 0)
3251
44.4k
    {
3252
44.4k
      DEBUG_TRACE ("FAIL on operand qualifier matching");
3253
44.4k
      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
44.4k
      return false;
3264
44.4k
    }
3265
3266
  /* Match operands' constraint.  */
3267
27.2M
  for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
3268
27.2M
    {
3269
27.2M
      enum aarch64_opnd type = inst->opcode->operands[i];
3270
27.2M
      if (type == AARCH64_OPND_NIL)
3271
8.06M
  break;
3272
19.2M
      if (inst->operands[i].skip)
3273
0
  {
3274
0
    DEBUG_TRACE ("skip the incomplete operand %d", i);
3275
0
    continue;
3276
0
  }
3277
19.2M
      if (!operand_general_constraint_met_p (inst->operands, i, type,
3278
19.2M
               inst->opcode, mismatch_detail))
3279
195k
  {
3280
195k
    DEBUG_TRACE ("FAIL on operand %d", i);
3281
195k
    return false;
3282
195k
  }
3283
19.2M
    }
3284
3285
  /* Check constraints involving multiple operands.  */
3286
8.06M
  if (inst->opcode->flags & F_REQUIRES_SP)
3287
5.55k
    {
3288
5.55k
      bool sp_found = false;
3289
15.8k
      for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
3290
15.8k
  {
3291
15.8k
    enum aarch64_opnd type = inst->opcode->operands[i];
3292
15.8k
    if (type == AARCH64_OPND_NIL)
3293
5.08k
      break;
3294
10.7k
    if (aarch64_stack_pointer_p (&(inst->operands[i])))
3295
461
      {
3296
461
        sp_found = true;
3297
461
        break;
3298
461
      }
3299
10.7k
  }
3300
5.55k
      if (!sp_found)
3301
5.08k
  {
3302
5.08k
    set_other_error (mismatch_detail, -1,
3303
5.08k
         _("expected at least one stack pointer operand"));
3304
5.08k
    return false;
3305
5.08k
  }
3306
5.55k
    }
3307
3308
8.05M
  DEBUG_TRACE ("PASS");
3309
3310
8.05M
  return true;
3311
8.06M
}
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
106k
{
3325
106k
  int i;
3326
106k
  const aarch64_opcode *old = inst->opcode;
3327
3328
106k
  inst->opcode = opcode;
3329
3330
  /* Update the operand types.  */
3331
390k
  for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
3332
390k
    {
3333
390k
      inst->operands[i].type = opcode->operands[i];
3334
390k
      if (opcode->operands[i] == AARCH64_OPND_NIL)
3335
106k
  break;
3336
390k
    }
3337
3338
106k
  DEBUG_TRACE ("replace %s with %s", old->name, opcode->name);
3339
3340
106k
  return old;
3341
106k
}
3342
3343
int
3344
aarch64_operand_index (const enum aarch64_opnd *operands, enum aarch64_opnd operand)
3345
197k
{
3346
197k
  int i;
3347
231k
  for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
3348
231k
    if (operands[i] == operand)
3349
192k
      return i;
3350
39.1k
    else if (operands[i] == AARCH64_OPND_NIL)
3351
5.37k
      break;
3352
5.37k
  return -1;
3353
197k
}
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.96M
{
3392
4.96M
  const int has_zr = sp_reg_p ? 0 : 1;
3393
4.96M
  const int is_64 = aarch64_get_qualifier_esize (qualifier) == 4 ? 0 : 1;
3394
4.96M
  return int_reg[has_zr][is_64][regno];
3395
4.96M
}
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.70M
{
3402
1.70M
  const int has_zr = sp_reg_p ? 0 : 1;
3403
1.70M
  return int_reg[has_zr][1][regno];
3404
1.70M
}
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
164k
{
3412
164k
  switch (opnd->shifter.kind)
3413
164k
    {
3414
2.11k
    case AARCH64_MOD_UXTW:
3415
4.61k
    case AARCH64_MOD_SXTW:
3416
4.61k
      return get_int_reg_name (opnd->addr.offset.regno, AARCH64_OPND_QLF_W, 0);
3417
3418
154k
    case AARCH64_MOD_LSL:
3419
159k
    case AARCH64_MOD_SXTX:
3420
159k
      return get_int_reg_name (opnd->addr.offset.regno, AARCH64_OPND_QLF_X, 0);
3421
3422
0
    default:
3423
0
      abort ();
3424
164k
    }
3425
164k
}
3426
3427
/* Get the name of the SVE vector offset register in OPND, using the operand
3428
   qualifier to decide whether the suffix should be .S or .D.  */
3429
3430
static inline const char *
3431
get_addr_sve_reg_name (int regno, aarch64_opnd_qualifier_t qualifier)
3432
143k
{
3433
143k
  assert (qualifier == AARCH64_OPND_QLF_S_S
3434
143k
    || qualifier == AARCH64_OPND_QLF_S_D);
3435
143k
  return sve_reg[qualifier == AARCH64_OPND_QLF_S_D][regno];
3436
143k
}
3437
3438
/* Types for expanding an encoded 8-bit value to a floating-point value.  */
3439
3440
typedef union
3441
{
3442
  uint64_t i;
3443
  double   d;
3444
} double_conv_t;
3445
3446
typedef union
3447
{
3448
  uint32_t i;
3449
  float    f;
3450
} single_conv_t;
3451
3452
typedef union
3453
{
3454
  uint32_t i;
3455
  float    f;
3456
} half_conv_t;
3457
3458
/* IMM8 is an 8-bit floating-point constant with sign, 3-bit exponent and
3459
   normalized 4 bits of precision, encoded in "a:b:c:d:e:f:g:h" or FLD_imm8
3460
   (depending on the type of the instruction).  IMM8 will be expanded to a
3461
   single-precision floating-point value (SIZE == 4) or a double-precision
3462
   floating-point value (SIZE == 8).  A half-precision floating-point value
3463
   (SIZE == 2) is expanded to a single-precision floating-point value.  The
3464
   expanded value is returned.  */
3465
3466
static uint64_t
3467
expand_fp_imm (int size, uint32_t imm8)
3468
3.14k
{
3469
3.14k
  uint64_t imm = 0;
3470
3.14k
  uint32_t imm8_7, imm8_6_0, imm8_6, imm8_6_repl4;
3471
3472
3.14k
  imm8_7 = (imm8 >> 7) & 0x01;  /* imm8<7>   */
3473
3.14k
  imm8_6_0 = imm8 & 0x7f; /* imm8<6:0> */
3474
3.14k
  imm8_6 = imm8_6_0 >> 6; /* imm8<6>   */
3475
3.14k
  imm8_6_repl4 = (imm8_6 << 3) | (imm8_6 << 2)
3476
3.14k
    | (imm8_6 << 1) | imm8_6; /* Replicate(imm8<6>,4) */
3477
3.14k
  if (size == 8)
3478
657
    {
3479
657
      imm = (imm8_7 << (63-32))   /* imm8<7>  */
3480
657
  | ((imm8_6 ^ 1) << (62-32)) /* NOT(imm8<6)  */
3481
657
  | (imm8_6_repl4 << (58-32)) | (imm8_6 << (57-32))
3482
657
  | (imm8_6 << (56-32)) | (imm8_6 << (55-32)) /* Replicate(imm8<6>,7) */
3483
657
  | (imm8_6_0 << (48-32));  /* imm8<6>:imm8<5:0>    */
3484
657
      imm <<= 32;
3485
657
    }
3486
2.48k
  else if (size == 4 || size == 2)
3487
2.48k
    {
3488
2.48k
      imm = (imm8_7 << 31)  /* imm8<7>              */
3489
2.48k
  | ((imm8_6 ^ 1) << 30)  /* NOT(imm8<6>)         */
3490
2.48k
  | (imm8_6_repl4 << 26)  /* Replicate(imm8<6>,4) */
3491
2.48k
  | (imm8_6_0 << 19); /* imm8<6>:imm8<5:0>    */
3492
2.48k
    }
3493
0
  else
3494
0
    {
3495
      /* An unsupported size.  */
3496
0
      assert (0);
3497
0
    }
3498
3499
3.14k
  return imm;
3500
3.14k
}
3501
3502
/* Return a string based on FMT with the register style applied.  */
3503
3504
static const char *
3505
style_reg (struct aarch64_styler *styler, const char *fmt, ...)
3506
12.1M
{
3507
12.1M
  const char *txt;
3508
12.1M
  va_list ap;
3509
3510
12.1M
  va_start (ap, fmt);
3511
12.1M
  txt = styler->apply_style (styler, dis_style_register, fmt, ap);
3512
12.1M
  va_end (ap);
3513
3514
12.1M
  return txt;
3515
12.1M
}
3516
3517
/* Return a string based on FMT with the immediate style applied.  */
3518
3519
static const char *
3520
style_imm (struct aarch64_styler *styler, const char *fmt, ...)
3521
4.96M
{
3522
4.96M
  const char *txt;
3523
4.96M
  va_list ap;
3524
3525
4.96M
  va_start (ap, fmt);
3526
4.96M
  txt = styler->apply_style (styler, dis_style_immediate, fmt, ap);
3527
4.96M
  va_end (ap);
3528
3529
4.96M
  return txt;
3530
4.96M
}
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
822k
{
3537
822k
  const char *txt;
3538
822k
  va_list ap;
3539
3540
822k
  va_start (ap, fmt);
3541
822k
  txt = styler->apply_style (styler, dis_style_sub_mnemonic, fmt, ap);
3542
822k
  va_end (ap);
3543
3544
822k
  return txt;
3545
822k
}
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.48M
{
3552
1.48M
  const char *txt;
3553
1.48M
  va_list ap;
3554
3555
1.48M
  va_start (ap, fmt);
3556
1.48M
  txt = styler->apply_style (styler, dis_style_address, fmt, ap);
3557
1.48M
  va_end (ap);
3558
3559
1.48M
  return txt;
3560
1.48M
}
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
422k
{
3569
422k
  const int mask = (prefix[0] == 'p' ? 15 : 31);
3570
422k
  const int num_regs = opnd->reglist.num_regs;
3571
422k
  const int stride = opnd->reglist.stride;
3572
422k
  const int first_reg = opnd->reglist.first_regno;
3573
422k
  const int last_reg = (first_reg + (num_regs - 1) * stride) & mask;
3574
422k
  const char *qlf_name = aarch64_get_qualifier_name (opnd->qualifier);
3575
422k
  char tb[16];  /* Temporary buffer.  */
3576
3577
422k
  assert (opnd->type != AARCH64_OPND_LEt || opnd->reglist.has_index);
3578
422k
  assert (num_regs >= 1 && num_regs <= 4);
3579
3580
  /* Prepare the index if any.  */
3581
422k
  if (opnd->reglist.has_index)
3582
    /* PR 21096: The %100 is to silence a warning about possible truncation.  */
3583
21.9k
    snprintf (tb, sizeof (tb), "[%s]",
3584
21.9k
        style_imm (styler, "%" PRIi64, (opnd->reglist.index % 100)));
3585
400k
  else
3586
400k
    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
422k
  if (stride == 1 && num_regs > 1)
3592
130k
    if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
3593
317
      snprintf (buf, size, "{%s-%s}%s",
3594
317
    style_reg (styler, "%s%d", prefix, first_reg),
3595
317
    style_reg (styler, "%s%d", prefix, last_reg), tb);
3596
129k
    else
3597
129k
      snprintf (buf, size, "{%s-%s}%s",
3598
129k
    style_reg (styler, "%s%d.%s", prefix, first_reg, qlf_name),
3599
129k
    style_reg (styler, "%s%d.%s", prefix, last_reg, qlf_name), tb);
3600
292k
  else
3601
292k
    {
3602
292k
      const int reg0 = first_reg;
3603
292k
      const int reg1 = (first_reg + stride) & mask;
3604
292k
      const int reg2 = (first_reg + stride * 2) & mask;
3605
292k
      const int reg3 = (first_reg + stride * 3) & mask;
3606
3607
292k
      switch (num_regs)
3608
292k
  {
3609
280k
  case 1:
3610
280k
    snprintf (buf, size, "{%s}%s",
3611
280k
        style_reg (styler, "%s%d.%s", prefix, reg0, qlf_name),
3612
280k
        tb);
3613
280k
    break;
3614
8.17k
  case 2:
3615
8.17k
    snprintf (buf, size, "{%s, %s}%s",
3616
8.17k
        style_reg (styler, "%s%d.%s", prefix, reg0, qlf_name),
3617
8.17k
        style_reg (styler, "%s%d.%s", prefix, reg1, qlf_name),
3618
8.17k
        tb);
3619
8.17k
    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
3.85k
  case 4:
3628
3.85k
    snprintf (buf, size, "{%s, %s, %s, %s}%s",
3629
3.85k
        style_reg (styler, "%s%d.%s", prefix, reg0, qlf_name),
3630
3.85k
        style_reg (styler, "%s%d.%s", prefix, reg1, qlf_name),
3631
3.85k
        style_reg (styler, "%s%d.%s", prefix, reg2, qlf_name),
3632
3.85k
        style_reg (styler, "%s%d.%s", prefix, reg3, qlf_name),
3633
3.85k
        tb);
3634
3.85k
    break;
3635
292k
  }
3636
292k
    }
3637
422k
}
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
919k
{
3648
919k
  if (opnd->addr.writeback)
3649
316k
    {
3650
316k
      if (opnd->addr.preind)
3651
161k
        {
3652
161k
    if (opnd->type == AARCH64_OPND_ADDR_SIMM10 && !opnd->addr.offset.imm)
3653
138
      snprintf (buf, size, "[%s]!", style_reg (styler, base));
3654
161k
          else
3655
161k
      snprintf (buf, size, "[%s, %s]!",
3656
161k
          style_reg (styler, base),
3657
161k
          style_imm (styler, "#%d", opnd->addr.offset.imm));
3658
161k
        }
3659
154k
      else
3660
154k
  snprintf (buf, size, "[%s], %s",
3661
154k
      style_reg (styler, base),
3662
154k
      style_imm (styler, "#%d", opnd->addr.offset.imm));
3663
316k
    }
3664
603k
  else
3665
603k
    {
3666
603k
      if (opnd->shifter.operator_present)
3667
92.3k
  {
3668
92.3k
    assert (opnd->shifter.kind == AARCH64_MOD_MUL_VL);
3669
92.3k
    snprintf (buf, size, "[%s, %s, %s]",
3670
92.3k
        style_reg (styler, base),
3671
92.3k
        style_imm (styler, "#%d", opnd->addr.offset.imm),
3672
92.3k
        style_sub_mnem (styler, "mul vl"));
3673
92.3k
  }
3674
511k
      else if (opnd->addr.offset.imm)
3675
414k
  snprintf (buf, size, "[%s, %s]",
3676
414k
      style_reg (styler, base),
3677
414k
      style_imm (styler, "#%d", opnd->addr.offset.imm));
3678
96.4k
      else
3679
96.4k
  snprintf (buf, size, "[%s]", style_reg (styler, base));
3680
603k
    }
3681
919k
}
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
288k
{
3692
288k
  char tb[32];      /* Temporary buffer.  */
3693
288k
  bool print_extend_p = true;
3694
288k
  bool print_amount_p = true;
3695
288k
  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
288k
  if (opnd->type == AARCH64_OPND_SVE_ADDR_ZX && offset != NULL
3700
15.7k
      && strcmp (offset,"xzr") == 0)
3701
515
    {
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
515
      snprintf (buf, size, "[%s]", style_reg (styler, base));
3706
515
    }
3707
288k
  else
3708
288k
    {
3709
288k
      if (!opnd->shifter.amount && (opnd->qualifier != AARCH64_OPND_QLF_S_B
3710
5.68k
            || !opnd->shifter.amount_present))
3711
135k
  {
3712
    /* Not print the shift/extend amount when the amount is zero and
3713
       when it is not the special case of 8-bit load/store
3714
       instruction.  */
3715
135k
   print_amount_p = false;
3716
   /* Likewise, no need to print the shift operator LSL in such a
3717
      situation.  */
3718
135k
   if (opnd->shifter.kind == AARCH64_MOD_LSL)
3719
85.2k
     print_extend_p = false;
3720
135k
  }
3721
3722
      /* Prepare for the extend/shift.  */
3723
288k
      if (print_extend_p)
3724
203k
  {
3725
203k
    if (print_amount_p)
3726
153k
      snprintf (tb, sizeof (tb), ", %s %s",
3727
153k
          style_sub_mnem (styler, shift_name),
3728
153k
          style_imm (styler, "#%" PRIi64,
3729
    /* PR 21096: The %100 is to silence a warning about possible
3730
       truncation.  */
3731
153k
         (opnd->shifter.amount % 100)));
3732
50.0k
    else
3733
50.0k
      snprintf (tb, sizeof (tb), ", %s",
3734
50.0k
          style_sub_mnem (styler, shift_name));
3735
203k
  }
3736
85.2k
      else
3737
85.2k
  tb[0] = '\0';
3738
3739
288k
      snprintf (buf, size, "[%s, %s%s]", style_reg (styler, base),
3740
288k
    style_reg (styler, offset), tb);
3741
288k
    }
3742
288k
}
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
285
{
3757
285
  static const struct {
3758
285
    unsigned char mask;
3759
285
    char name[7];
3760
285
  } zan[] = {
3761
285
    { 0xff, "za" },
3762
285
    { 0x55, "za0.h" },
3763
285
    { 0xaa, "za1.h" },
3764
285
    { 0x11, "za0.s" },
3765
285
    { 0x22, "za1.s" },
3766
285
    { 0x44, "za2.s" },
3767
285
    { 0x88, "za3.s" },
3768
285
    { 0x01, "za0.d" },
3769
285
    { 0x02, "za1.d" },
3770
285
    { 0x04, "za2.d" },
3771
285
    { 0x08, "za3.d" },
3772
285
    { 0x10, "za4.d" },
3773
285
    { 0x20, "za5.d" },
3774
285
    { 0x40, "za6.d" },
3775
285
    { 0x80, "za7.d" },
3776
285
    { 0x00, " " },
3777
285
  };
3778
285
  int k;
3779
3780
285
  k = snprintf (buf, size, "{");
3781
2.61k
  for (unsigned int i = 0; i < ARRAY_SIZE (zan); i++)
3782
2.61k
    {
3783
2.61k
      if ((mask & zan[i].mask) == zan[i].mask)
3784
871
  {
3785
871
    mask &= ~zan[i].mask;
3786
871
    if (k > 1)
3787
591
      k += snprintf (buf + k, size - k, ", ");
3788
3789
871
    k += snprintf (buf + k, size - k, "%s",
3790
871
       style_reg (styler, zan[i].name));
3791
871
  }
3792
2.61k
      if (mask == 0)
3793
285
        break;
3794
2.61k
    }
3795
285
  snprintf (buf + k, size - k, "}");
3796
285
}
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
16.0M
{
3818
16.0M
  unsigned int i, num_conds;
3819
16.0M
  const char *name = NULL;
3820
16.0M
  const aarch64_opnd_info *opnd = opnds + idx;
3821
16.0M
  enum aarch64_modifier_kind kind;
3822
16.0M
  uint64_t addr, enum_value;
3823
3824
16.0M
  if (comment != NULL)
3825
16.0M
    {
3826
16.0M
      assert (comment_size > 0);
3827
16.0M
      comment[0] = '\0';
3828
16.0M
    }
3829
0
  else
3830
16.0M
    assert (comment_size == 0);
3831
3832
16.0M
  buf[0] = '\0';
3833
16.0M
  if (pcrel_p)
3834
16.0M
    *pcrel_p = 0;
3835
3836
16.0M
  switch (opnd->type)
3837
16.0M
    {
3838
1.25M
    case AARCH64_OPND_Rd:
3839
1.90M
    case AARCH64_OPND_Rn:
3840
2.03M
    case AARCH64_OPND_Rm:
3841
3.35M
    case AARCH64_OPND_Rt:
3842
3.65M
    case AARCH64_OPND_Rt2:
3843
3.82M
    case AARCH64_OPND_Rs:
3844
3.85M
    case AARCH64_OPND_Ra:
3845
3.85M
    case AARCH64_OPND_Rt_IN_SYS_ALIASES:
3846
3.85M
    case AARCH64_OPND_Rt_LS64:
3847
3.85M
    case AARCH64_OPND_Rt_SYS:
3848
3.85M
    case AARCH64_OPND_PAIRREG:
3849
3.86M
    case AARCH64_OPND_PAIRREG_OR_XZR:
3850
3.86M
    case AARCH64_OPND_SVE_Rm:
3851
3.86M
    case AARCH64_OPND_LSE128_Rt:
3852
3.86M
    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.86M
      if (opnd->type == AARCH64_OPND_Rt_SYS)
3857
329
  {
3858
329
    if (!opnd->present)
3859
17
      break;
3860
329
  }
3861
3.86M
      else if ((opnd->type == AARCH64_OPND_Rt_IN_SYS_ALIASES)
3862
39
         && (opnd->reg.regno
3863
39
       != get_optional_operand_default_value (opcode)))
3864
39
  {
3865
    /* Avoid printing an invalid additional value for Rt in SYS aliases such as
3866
       BRB, provide a helpful comment instead */
3867
39
    snprintf (comment, comment_size, "unpredictable encoding (Rt!=31): #%u", opnd->reg.regno);
3868
39
    break;
3869
39
  }
3870
      /* Omit the operand, e.g. RET.  */
3871
3.86M
      else if (optional_operand_p (opcode, idx)
3872
5.58k
         && (opnd->reg.regno
3873
5.58k
       == get_optional_operand_default_value (opcode)))
3874
2.26k
  break;
3875
3.86M
      assert (opnd->qualifier == AARCH64_OPND_QLF_W
3876
3.85M
        || opnd->qualifier == AARCH64_OPND_QLF_X);
3877
3.85M
      snprintf (buf, size, "%s",
3878
3.85M
    style_reg (styler, get_int_reg_name (opnd->reg.regno,
3879
3.85M
                 opnd->qualifier, 0)));
3880
3.85M
      break;
3881
3882
250k
    case AARCH64_OPND_Rd_SP:
3883
523k
    case AARCH64_OPND_Rn_SP:
3884
530k
    case AARCH64_OPND_Rt_SP:
3885
531k
    case AARCH64_OPND_SVE_Rn_SP:
3886
532k
    case AARCH64_OPND_Rm_SP:
3887
532k
      assert (opnd->qualifier == AARCH64_OPND_QLF_W
3888
532k
        || opnd->qualifier == AARCH64_OPND_QLF_X);
3889
532k
      snprintf (buf, size, "%s",
3890
532k
    style_reg (styler, get_int_reg_name (opnd->reg.regno,
3891
532k
                 opnd->qualifier, 1)));
3892
532k
      break;
3893
3894
26.3k
    case AARCH64_OPND_Rm_EXT:
3895
26.3k
      kind = opnd->shifter.kind;
3896
26.3k
      assert (idx == 1 || idx == 2);
3897
26.3k
      if ((aarch64_stack_pointer_p (opnds)
3898
25.5k
     || (idx == 2 && aarch64_stack_pointer_p (opnds + 1)))
3899
1.99k
    && ((opnd->qualifier == AARCH64_OPND_QLF_W
3900
961
         && opnds[0].qualifier == AARCH64_OPND_QLF_W
3901
522
         && kind == AARCH64_MOD_UXTW)
3902
1.91k
        || (opnd->qualifier == AARCH64_OPND_QLF_X
3903
1.03k
      && kind == AARCH64_MOD_UXTX)))
3904
895
  {
3905
    /* 'LSL' is the preferred form in this case.  */
3906
895
    kind = AARCH64_MOD_LSL;
3907
895
    if (opnd->shifter.amount == 0)
3908
434
      {
3909
        /* Shifter omitted.  */
3910
434
        snprintf (buf, size, "%s",
3911
434
      style_reg (styler,
3912
434
           get_int_reg_name (opnd->reg.regno,
3913
434
                 opnd->qualifier, 0)));
3914
434
        break;
3915
434
      }
3916
895
  }
3917
25.9k
      if (opnd->shifter.amount)
3918
19.9k
  snprintf (buf, size, "%s, %s %s",
3919
19.9k
      style_reg (styler, get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0)),
3920
19.9k
      style_sub_mnem (styler, aarch64_operand_modifiers[kind].name),
3921
19.9k
      style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
3922
6.03k
      else
3923
6.03k
  snprintf (buf, size, "%s, %s",
3924
6.03k
      style_reg (styler, get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0)),
3925
6.03k
      style_sub_mnem (styler, aarch64_operand_modifiers[kind].name));
3926
25.9k
      break;
3927
3928
356k
    case AARCH64_OPND_Rm_SFT:
3929
356k
      assert (opnd->qualifier == AARCH64_OPND_QLF_W
3930
356k
        || opnd->qualifier == AARCH64_OPND_QLF_X);
3931
356k
      if (opnd->shifter.amount == 0 && opnd->shifter.kind == AARCH64_MOD_LSL)
3932
40.8k
  snprintf (buf, size, "%s",
3933
40.8k
      style_reg (styler, get_int_reg_name (opnd->reg.regno,
3934
40.8k
                   opnd->qualifier, 0)));
3935
315k
      else
3936
315k
  snprintf (buf, size, "%s, %s %s",
3937
315k
      style_reg (styler, get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0)),
3938
315k
      style_sub_mnem (styler, aarch64_operand_modifiers[opnd->shifter.kind].name),
3939
315k
      style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
3940
356k
      break;
3941
3942
929
    case AARCH64_OPND_Rm_LSL:
3943
929
      assert (opnd->qualifier == AARCH64_OPND_QLF_X);
3944
929
      assert (opnd->shifter.kind == AARCH64_MOD_LSL);
3945
929
      if (opnd->shifter.amount == 0)
3946
281
  snprintf (buf, size, "%s",
3947
281
      style_reg (styler, get_int_reg_name (opnd->reg.regno,
3948
281
                   opnd->qualifier, 0)));
3949
648
      else
3950
648
  snprintf (buf, size, "%s, %s %s",
3951
648
      style_reg (styler, get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0)),
3952
648
      style_sub_mnem (styler, aarch64_operand_modifiers[opnd->shifter.kind].name),
3953
648
      style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
3954
929
      break;
3955
3956
121k
    case AARCH64_OPND_Fd:
3957
166k
    case AARCH64_OPND_Fn:
3958
221k
    case AARCH64_OPND_Fm:
3959
316k
    case AARCH64_OPND_Fa:
3960
815k
    case AARCH64_OPND_Ft:
3961
1.06M
    case AARCH64_OPND_Ft2:
3962
1.08M
    case AARCH64_OPND_Sd:
3963
1.10M
    case AARCH64_OPND_Sn:
3964
1.11M
    case AARCH64_OPND_Sm:
3965
1.11M
    case AARCH64_OPND_SVE_VZn:
3966
1.12M
    case AARCH64_OPND_SVE_Vd:
3967
1.12M
    case AARCH64_OPND_SVE_Vm:
3968
1.12M
    case AARCH64_OPND_SVE_Vn:
3969
1.12M
      snprintf (buf, size, "%s",
3970
1.12M
    style_reg (styler, "%s%d",
3971
1.12M
         aarch64_get_qualifier_name (opnd->qualifier),
3972
1.12M
         opnd->reg.regno));
3973
1.12M
      break;
3974
3975
10.9k
    case AARCH64_OPND_Va:
3976
308k
    case AARCH64_OPND_Vd:
3977
567k
    case AARCH64_OPND_Vn:
3978
743k
    case AARCH64_OPND_Vm:
3979
743k
      snprintf (buf, size, "%s",
3980
743k
    style_reg (styler, "v%d.%s", opnd->reg.regno,
3981
743k
         aarch64_get_qualifier_name (opnd->qualifier)));
3982
743k
      break;
3983
3984
1.76k
    case AARCH64_OPND_Ed:
3985
7.36k
    case AARCH64_OPND_En:
3986
43.6k
    case AARCH64_OPND_Em:
3987
92.1k
    case AARCH64_OPND_Em16:
3988
95.8k
    case AARCH64_OPND_Em8:
3989
95.8k
      snprintf (buf, size, "%s[%s]",
3990
95.8k
    style_reg (styler, "v%d.%s", opnd->reglane.regno,
3991
95.8k
         aarch64_get_qualifier_name (opnd->qualifier)),
3992
95.8k
    style_imm (styler, "%" PRIi64, opnd->reglane.index));
3993
95.8k
      break;
3994
3995
1.22k
    case AARCH64_OPND_Em_INDEX1_14:
3996
3.00k
    case AARCH64_OPND_Em_INDEX2_13:
3997
3.83k
    case AARCH64_OPND_Em_INDEX3_12:
3998
3.83k
      snprintf (buf, size, "%s[%s]",
3999
3.83k
    style_reg (styler, "v%d", opnd->reglane.regno),
4000
3.83k
    style_imm (styler, "%" PRIi64, opnd->reglane.index));
4001
3.83k
      break;
4002
4003
314
    case AARCH64_OPND_VdD1:
4004
1.07k
    case AARCH64_OPND_VnD1:
4005
1.07k
      snprintf (buf, size, "%s[%s]",
4006
1.07k
    style_reg (styler, "v%d.d", opnd->reg.regno),
4007
1.07k
    style_imm (styler, "1"));
4008
1.07k
      break;
4009
4010
16.9k
    case AARCH64_OPND_LVn:
4011
20.7k
    case AARCH64_OPND_LVn_LUT:
4012
35.1k
    case AARCH64_OPND_LVt:
4013
37.3k
    case AARCH64_OPND_LVt_AL:
4014
59.0k
    case AARCH64_OPND_LEt:
4015
59.0k
      print_register_list (buf, size, opnd, "v", styler);
4016
59.0k
      break;
4017
4018
88.3k
    case AARCH64_OPND_SVE_Pd:
4019
779k
    case AARCH64_OPND_SVE_Pg3:
4020
779k
    case AARCH64_OPND_SVE_Pg4_5:
4021
799k
    case AARCH64_OPND_SVE_Pg4_10:
4022
807k
    case AARCH64_OPND_SVE_Pg4_16:
4023
815k
    case AARCH64_OPND_SVE_Pm:
4024
824k
    case AARCH64_OPND_SVE_Pn:
4025
825k
    case AARCH64_OPND_SVE_Pt:
4026
905k
    case AARCH64_OPND_SME_Pm:
4027
905k
      if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
4028
161k
  snprintf (buf, size, "%s",
4029
161k
      style_reg (styler, "p%d", opnd->reg.regno));
4030
744k
      else if (opnd->qualifier == AARCH64_OPND_QLF_P_Z
4031
437k
         || opnd->qualifier == AARCH64_OPND_QLF_P_M)
4032
643k
  snprintf (buf, size, "%s",
4033
643k
      style_reg (styler, "p%d/%s", opnd->reg.regno,
4034
643k
           aarch64_get_qualifier_name (opnd->qualifier)));
4035
100k
      else
4036
100k
  snprintf (buf, size, "%s",
4037
100k
      style_reg (styler, "p%d.%s", opnd->reg.regno,
4038
100k
           aarch64_get_qualifier_name (opnd->qualifier)));
4039
905k
      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
1.96k
    case AARCH64_OPND_SME_PNd3:
4046
33.5k
    case AARCH64_OPND_SME_PNg3:
4047
33.5k
    case AARCH64_OPND_SME_PNn:
4048
33.5k
      if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
4049
10.5k
  snprintf (buf, size, "%s",
4050
10.5k
      style_reg (styler, "pn%d", opnd->reg.regno));
4051
22.9k
      else if (opnd->qualifier == AARCH64_OPND_QLF_P_Z
4052
1.99k
         || opnd->qualifier == AARCH64_OPND_QLF_P_M)
4053
21.0k
  snprintf (buf, size, "%s",
4054
21.0k
      style_reg (styler, "pn%d/%s", opnd->reg.regno,
4055
21.0k
           aarch64_get_qualifier_name (opnd->qualifier)));
4056
1.99k
      else
4057
1.99k
  snprintf (buf, size, "%s",
4058
1.99k
      style_reg (styler, "pn%d.%s", opnd->reg.regno,
4059
1.99k
           aarch64_get_qualifier_name (opnd->qualifier)));
4060
33.5k
      break;
4061
4062
895
    case AARCH64_OPND_SME_Pdx2:
4063
1.00k
    case AARCH64_OPND_SME_PdxN:
4064
1.00k
      print_register_list (buf, size, opnd, "p", styler);
4065
1.00k
      break;
4066
4067
109
    case AARCH64_OPND_SME_PNn3_INDEX1:
4068
157
    case AARCH64_OPND_SME_PNn3_INDEX2:
4069
157
      snprintf (buf, size, "%s[%s]",
4070
157
    style_reg (styler, "pn%d", opnd->reglane.regno),
4071
157
    style_imm (styler, "%" PRIi64, opnd->reglane.index));
4072
157
      break;
4073
4074
8.24k
    case AARCH64_OPND_SVE_Za_5:
4075
17.1k
    case AARCH64_OPND_SVE_Za_16:
4076
459k
    case AARCH64_OPND_SVE_Zd:
4077
505k
    case AARCH64_OPND_SVE_Zm_5:
4078
825k
    case AARCH64_OPND_SVE_Zm_16:
4079
1.31M
    case AARCH64_OPND_SVE_Zn:
4080
1.31M
    case AARCH64_OPND_SVE_Zt:
4081
1.32M
    case AARCH64_OPND_SME_Zm:
4082
1.32M
    case AARCH64_OPND_SME_Zm_17:
4083
1.33M
    case AARCH64_OPND_SME_Zn_6_3:
4084
1.34M
    case AARCH64_OPND_SME_Zm_17_3:
4085
1.34M
      if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
4086
3.02k
       snprintf (buf, size, "%s", style_reg (styler, "z%d", opnd->reg.regno));
4087
1.34M
      else
4088
1.34M
       snprintf (buf, size, "%s",
4089
1.34M
     style_reg (styler, "z%d.%s", opnd->reg.regno,
4090
1.34M
          aarch64_get_qualifier_name (opnd->qualifier)));
4091
1.34M
      break;
4092
4093
13.0k
    case AARCH64_OPND_SVE_ZnxN:
4094
295k
    case AARCH64_OPND_SVE_ZtxN:
4095
317k
    case AARCH64_OPND_SME_Zdnx2:
4096
323k
    case AARCH64_OPND_SME_Zdnx4:
4097
324k
    case AARCH64_OPND_SME_Znx2_6_3:
4098
325k
    case AARCH64_OPND_SME_Zmx2_17_3:
4099
327k
    case AARCH64_OPND_SME_Zmx2:
4100
328k
    case AARCH64_OPND_SME_Zmx4:
4101
328k
    case AARCH64_OPND_SME_Zmx2_INDEX_22:
4102
345k
    case AARCH64_OPND_SME_Znx2:
4103
345k
    case AARCH64_OPND_SME_Znx2_BIT_INDEX:
4104
350k
    case AARCH64_OPND_SME_Znx4:
4105
350k
    case AARCH64_OPND_SME_Zn7xN_UNTYPED:
4106
358k
    case AARCH64_OPND_SME_Ztx2_STRIDED:
4107
362k
    case AARCH64_OPND_SME_Ztx4_STRIDED:
4108
362k
      print_register_list (buf, size, opnd, "z", styler);
4109
362k
      break;
4110
4111
443
    case AARCH64_OPND_SVE_Zm1_23_INDEX:
4112
1.71k
    case AARCH64_OPND_SVE_Zm2_22_INDEX:
4113
6.74k
    case AARCH64_OPND_SVE_Zm3_INDEX:
4114
15.9k
    case AARCH64_OPND_SVE_Zm3_22_INDEX:
4115
16.2k
    case AARCH64_OPND_SVE_Zm3_19_INDEX:
4116
17.2k
    case AARCH64_OPND_SVE_Zm3_12_INDEX:
4117
24.0k
    case AARCH64_OPND_SVE_Zm3_11_INDEX:
4118
28.2k
    case AARCH64_OPND_SVE_Zm3_10_INDEX:
4119
31.6k
    case AARCH64_OPND_SVE_Zm4_11_INDEX:
4120
37.1k
    case AARCH64_OPND_SVE_Zm4_INDEX:
4121
38.0k
    case AARCH64_OPND_SVE_Zn_INDEX:
4122
42.6k
    case AARCH64_OPND_SME_Zk_INDEX:
4123
42.9k
    case AARCH64_OPND_SME_Zm_INDEX1:
4124
45.7k
    case AARCH64_OPND_SME_Zm_INDEX2:
4125
45.8k
    case AARCH64_OPND_SME_Zm_INDEX2_3:
4126
47.8k
    case AARCH64_OPND_SME_Zm_INDEX3_1:
4127
50.2k
    case AARCH64_OPND_SME_Zm_INDEX3_2:
4128
51.0k
    case AARCH64_OPND_SME_Zm_INDEX3_3:
4129
55.8k
    case AARCH64_OPND_SME_Zm_INDEX3_10:
4130
56.2k
    case AARCH64_OPND_SVE_Zn_5_INDEX:
4131
58.4k
    case AARCH64_OPND_SME_Zm_INDEX4_1:
4132
59.3k
    case AARCH64_OPND_SME_Zm_INDEX4_2:
4133
78.0k
    case AARCH64_OPND_SME_Zm_INDEX4_3:
4134
83.8k
    case AARCH64_OPND_SME_Zm_INDEX4_10:
4135
84.1k
    case AARCH64_OPND_SME_Zn_INDEX1_16:
4136
84.4k
    case AARCH64_OPND_SME_Zn_INDEX2_15:
4137
84.9k
    case AARCH64_OPND_SME_Zn_INDEX2_16:
4138
85.1k
    case AARCH64_OPND_SME_Zn_INDEX2_19:
4139
85.3k
    case AARCH64_OPND_SME_Zn_INDEX3_14:
4140
85.6k
    case AARCH64_OPND_SME_Zn_INDEX3_15:
4141
85.8k
    case AARCH64_OPND_SME_Zn_INDEX4_14:
4142
85.8k
      snprintf (buf, size, "%s[%s]",
4143
85.8k
    (opnd->qualifier == AARCH64_OPND_QLF_NIL
4144
85.8k
     ? style_reg (styler, "z%d", opnd->reglane.regno)
4145
85.8k
     : style_reg (styler, "z%d.%s", opnd->reglane.regno,
4146
76.6k
            aarch64_get_qualifier_name (opnd->qualifier))),
4147
85.8k
    style_imm (styler, "%" PRIi64, opnd->reglane.index));
4148
85.8k
      break;
4149
4150
79
    case AARCH64_OPND_SVE_Zn0_INDEX:
4151
184
    case AARCH64_OPND_SVE_Zn1_17_INDEX:
4152
313
    case AARCH64_OPND_SVE_Zn2_18_INDEX:
4153
436
    case AARCH64_OPND_SVE_Zn3_22_INDEX:
4154
526
    case AARCH64_OPND_SVE_Zd0_INDEX:
4155
626
    case AARCH64_OPND_SVE_Zd1_17_INDEX:
4156
713
    case AARCH64_OPND_SVE_Zd2_18_INDEX:
4157
742
    case AARCH64_OPND_SVE_Zd3_22_INDEX:
4158
742
      if (opnd->reglane.index == 0)
4159
270
  snprintf (buf, size, "%s", style_reg (styler, "z%d", opnd->reg.regno));
4160
472
      else
4161
472
  snprintf (buf, size, "%s[%s]",
4162
472
      style_reg (styler, "z%d", opnd->reglane.regno),
4163
472
      style_imm (styler, "%" PRIi64, opnd->reglane.index));
4164
742
      break;
4165
4166
2.12k
    case AARCH64_OPND_SME_ZAda_1b:
4167
75.9k
    case AARCH64_OPND_SME_ZAda_2b:
4168
94.2k
    case AARCH64_OPND_SME_ZAda_3b:
4169
94.2k
      snprintf (buf, size, "%s",
4170
94.2k
    style_reg (styler, "za%d.%s", opnd->reg.regno,
4171
94.2k
         aarch64_get_qualifier_name (opnd->qualifier)));
4172
94.2k
      break;
4173
4174
661
    case AARCH64_OPND_SME_ZA_HV_idx_src:
4175
3.35k
    case AARCH64_OPND_SME_ZA_HV_idx_srcxN:
4176
41.6k
    case AARCH64_OPND_SME_ZA_HV_idx_dest:
4177
42.7k
    case AARCH64_OPND_SME_ZA_HV_idx_destxN:
4178
94.6k
    case AARCH64_OPND_SME_ZA_HV_idx_ldstr:
4179
94.8k
    case AARCH64_OPND_SME_ZA_array_vrsb_1:
4180
94.9k
    case AARCH64_OPND_SME_ZA_array_vrsh_1:
4181
94.9k
    case AARCH64_OPND_SME_ZA_array_vrss_1:
4182
95.2k
    case AARCH64_OPND_SME_ZA_array_vrsd_1:
4183
95.4k
    case AARCH64_OPND_SME_ZA_array_vrsb_2:
4184
95.5k
    case AARCH64_OPND_SME_ZA_array_vrsh_2:
4185
95.7k
    case AARCH64_OPND_SME_ZA_array_vrss_2:
4186
96.1k
    case AARCH64_OPND_SME_ZA_array_vrsd_2:
4187
96.9k
    case AARCH64_OPND_SME_ZA_ARRAY4:
4188
96.9k
      snprintf (buf, size, "%s%s[%s, %s%s%s%s%s]%s",
4189
96.9k
    opnd->type == AARCH64_OPND_SME_ZA_HV_idx_ldstr ? "{" : "",
4190
96.9k
    style_reg (styler, "za%d%c%s%s",
4191
96.9k
         opnd->indexed_za.regno,
4192
96.9k
         opnd->indexed_za.v == 1 ? 'v' : 'h',
4193
96.9k
         opnd->qualifier == AARCH64_OPND_QLF_NIL ? "" : ".",
4194
96.9k
         (opnd->qualifier == AARCH64_OPND_QLF_NIL
4195
96.9k
          ? ""
4196
96.9k
          : aarch64_get_qualifier_name (opnd->qualifier))),
4197
96.9k
    style_reg (styler, "w%d", opnd->indexed_za.index.regno),
4198
96.9k
    style_imm (styler, "%" PRIi64, opnd->indexed_za.index.imm),
4199
96.9k
    opnd->indexed_za.index.countm1 ? ":" : "",
4200
96.9k
    (opnd->indexed_za.index.countm1
4201
96.9k
     ? style_imm (styler, "%d",
4202
5.23k
            opnd->indexed_za.index.imm
4203
5.23k
            + opnd->indexed_za.index.countm1)
4204
96.9k
     : ""),
4205
96.9k
    opnd->indexed_za.group_size ? ", " : "",
4206
96.9k
    opnd->indexed_za.group_size == 2
4207
96.9k
    ? style_sub_mnem (styler, "vgx2")
4208
96.9k
    : opnd->indexed_za.group_size == 4
4209
96.9k
    ? style_sub_mnem (styler, "vgx4") : "",
4210
96.9k
    opnd->type == AARCH64_OPND_SME_ZA_HV_idx_ldstr ? "}" : "");
4211
96.9k
      break;
4212
4213
285
    case AARCH64_OPND_SME_list_of_64bit_tiles:
4214
285
      print_sme_za_list (buf, size, opnd->imm.value, styler);
4215
285
      break;
4216
4217
6.54k
    case AARCH64_OPND_SME_ZA_array_off1x4:
4218
11.8k
    case AARCH64_OPND_SME_ZA_array_off2x2:
4219
18.8k
    case AARCH64_OPND_SME_ZA_array_off2x4:
4220
28.8k
    case AARCH64_OPND_SME_ZA_array_off3_0:
4221
29.2k
    case AARCH64_OPND_SME_ZA_array_off3_5:
4222
53.0k
    case AARCH64_OPND_SME_ZA_array_off3x2:
4223
54.1k
    case AARCH64_OPND_SME_ZA_array_off4:
4224
54.1k
      snprintf (buf, size, "%s[%s, %s%s%s%s%s]",
4225
54.1k
    style_reg (styler, "za%s%s",
4226
54.1k
         opnd->qualifier == AARCH64_OPND_QLF_NIL ? "" : ".",
4227
54.1k
         (opnd->qualifier == AARCH64_OPND_QLF_NIL
4228
54.1k
          ? ""
4229
54.1k
          : aarch64_get_qualifier_name (opnd->qualifier))),
4230
54.1k
    style_reg (styler, "w%d", opnd->indexed_za.index.regno),
4231
54.1k
    style_imm (styler, "%" PRIi64, opnd->indexed_za.index.imm),
4232
54.1k
    opnd->indexed_za.index.countm1 ? ":" : "",
4233
54.1k
    (opnd->indexed_za.index.countm1
4234
54.1k
     ? style_imm (styler, "%d",
4235
42.5k
            opnd->indexed_za.index.imm
4236
42.5k
            + opnd->indexed_za.index.countm1)
4237
54.1k
     : ""),
4238
54.1k
    opnd->indexed_za.group_size ? ", " : "",
4239
54.1k
    opnd->indexed_za.group_size == 2
4240
54.1k
    ? style_sub_mnem (styler, "vgx2")
4241
54.1k
    : opnd->indexed_za.group_size == 4
4242
40.2k
    ? style_sub_mnem (styler, "vgx4") : "");
4243
54.1k
      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
4.32k
    case AARCH64_OPND_SME_PnT_Wm_imm:
4251
4.32k
      snprintf (buf, size, "%s[%s, %s]",
4252
4.32k
    style_reg (styler, "p%d.%s", opnd->indexed_za.regno,
4253
4.32k
         aarch64_get_qualifier_name (opnd->qualifier)),
4254
4.32k
    style_reg (styler, "w%d", opnd->indexed_za.index.regno),
4255
4.32k
    style_imm (styler, "%" PRIi64, opnd->indexed_za.index.imm));
4256
4.32k
      break;
4257
4258
35
    case AARCH64_OPND_SME_VLxN_10:
4259
1.99k
    case AARCH64_OPND_SME_VLxN_13:
4260
1.99k
      enum_value = opnd->imm.value;
4261
1.99k
      assert (enum_value < ARRAY_SIZE (aarch64_sme_vlxn_array));
4262
1.99k
      snprintf (buf, size, "%s",
4263
1.99k
    style_sub_mnem (styler, aarch64_sme_vlxn_array[enum_value]));
4264
1.99k
      break;
4265
4266
39
    case AARCH64_OPND_BRBOP:
4267
39
      enum_value = opnd->imm.value;
4268
39
      assert (enum_value < ARRAY_SIZE (aarch64_brbop_array));
4269
39
      snprintf (buf, size, "%s",
4270
39
    style_sub_mnem (styler, aarch64_brbop_array[enum_value]));
4271
39
      break;
4272
4273
4.73k
    case AARCH64_OPND_CRn:
4274
9.47k
    case AARCH64_OPND_CRm:
4275
9.47k
      snprintf (buf, size, "%s",
4276
9.47k
    style_reg (styler, "C%" PRIi64, opnd->imm.value));
4277
9.47k
      break;
4278
4279
11.2k
    case AARCH64_OPND_IDX:
4280
11.7k
    case AARCH64_OPND_MASK:
4281
51.1k
    case AARCH64_OPND_IMM:
4282
77.4k
    case AARCH64_OPND_IMM_2:
4283
112k
    case AARCH64_OPND_WIDTH:
4284
116k
    case AARCH64_OPND_UIMM3_OP1:
4285
121k
    case AARCH64_OPND_UIMM3_OP2:
4286
285k
    case AARCH64_OPND_BIT_NUM:
4287
292k
    case AARCH64_OPND_IMM_VLSL:
4288
307k
    case AARCH64_OPND_IMM_VLSR:
4289
307k
    case AARCH64_OPND_SHLL_IMM:
4290
307k
    case AARCH64_OPND_IMM0:
4291
307k
    case AARCH64_OPND_IMMR:
4292
311k
    case AARCH64_OPND_IMMS:
4293
2.20M
    case AARCH64_OPND_UNDEFINED:
4294
2.20M
    case AARCH64_OPND_FBITS:
4295
2.20M
    case AARCH64_OPND_TME_UIMM16:
4296
2.22M
    case AARCH64_OPND_SIMM5:
4297
2.22M
    case AARCH64_OPND_SME_SHRIMM3:
4298
2.22M
    case AARCH64_OPND_SME_SHRIMM4:
4299
2.22M
    case AARCH64_OPND_SME_SHRIMM5:
4300
2.22M
    case AARCH64_OPND_SVE_SHLIMM_PRED:
4301
2.22M
    case AARCH64_OPND_SVE_SHLIMM_UNPRED:
4302
2.22M
    case AARCH64_OPND_SVE_SHLIMM_UNPRED_22:
4303
2.22M
    case AARCH64_OPND_SVE_SHRIMM_PRED:
4304
2.22M
    case AARCH64_OPND_SVE_SHRIMM_UNPRED:
4305
2.23M
    case AARCH64_OPND_SVE_SHRIMM_UNPRED_22:
4306
2.23M
    case AARCH64_OPND_SVE_SIMM5:
4307
2.23M
    case AARCH64_OPND_SVE_SIMM5B:
4308
2.23M
    case AARCH64_OPND_SVE_SIMM6:
4309
2.23M
    case AARCH64_OPND_SVE_SIMM8:
4310
2.23M
    case AARCH64_OPND_SVE_UIMM3:
4311
2.26M
    case AARCH64_OPND_SVE_UIMM7:
4312
2.26M
    case AARCH64_OPND_SVE_UIMM8:
4313
2.26M
    case AARCH64_OPND_SVE_UIMM4:
4314
2.26M
    case AARCH64_OPND_SVE_UIMM8_53:
4315
2.26M
    case AARCH64_OPND_IMM_ROT1:
4316
2.28M
    case AARCH64_OPND_IMM_ROT2:
4317
2.28M
    case AARCH64_OPND_IMM_ROT3:
4318
2.28M
    case AARCH64_OPND_SVE_IMM_ROT1:
4319
2.29M
    case AARCH64_OPND_SVE_IMM_ROT2:
4320
2.29M
    case AARCH64_OPND_SVE_IMM_ROT3:
4321
2.29M
    case AARCH64_OPND_CSSC_SIMM8:
4322
2.29M
    case AARCH64_OPND_CSSC_UIMM8:
4323
2.29M
      snprintf (buf, size, "%s",
4324
2.29M
    style_imm (styler, "#%" PRIi64, opnd->imm.value));
4325
2.29M
      break;
4326
4327
97
    case AARCH64_OPND_SVE_I1_HALF_ONE:
4328
365
    case AARCH64_OPND_SVE_I1_HALF_TWO:
4329
1.55k
    case AARCH64_OPND_SVE_I1_ZERO_ONE:
4330
1.55k
      {
4331
1.55k
  single_conv_t c;
4332
1.55k
  c.i = opnd->imm.value;
4333
1.55k
  snprintf (buf, size, "%s", style_imm (styler, "#%.1f", c.f));
4334
1.55k
  break;
4335
365
      }
4336
4337
186
    case AARCH64_OPND_SVE_PATTERN:
4338
186
      if (optional_operand_p (opcode, idx)
4339
186
    && opnd->imm.value == get_optional_operand_default_value (opcode))
4340
56
  break;
4341
130
      enum_value = opnd->imm.value;
4342
130
      assert (enum_value < ARRAY_SIZE (aarch64_sve_pattern_array));
4343
130
      if (aarch64_sve_pattern_array[enum_value])
4344
57
  snprintf (buf, size, "%s",
4345
57
      style_reg (styler, aarch64_sve_pattern_array[enum_value]));
4346
73
      else
4347
73
  snprintf (buf, size, "%s",
4348
73
      style_imm (styler, "#%" PRIi64, opnd->imm.value));
4349
130
      break;
4350
4351
7.39k
    case AARCH64_OPND_SVE_PATTERN_SCALED:
4352
7.39k
      if (optional_operand_p (opcode, idx)
4353
7.39k
    && !opnd->shifter.operator_present
4354
1.15k
    && opnd->imm.value == get_optional_operand_default_value (opcode))
4355
554
  break;
4356
6.84k
      enum_value = opnd->imm.value;
4357
6.84k
      assert (enum_value < ARRAY_SIZE (aarch64_sve_pattern_array));
4358
6.84k
      if (aarch64_sve_pattern_array[opnd->imm.value])
4359
4.73k
  snprintf (buf, size, "%s",
4360
4.73k
      style_reg (styler,
4361
4.73k
           aarch64_sve_pattern_array[opnd->imm.value]));
4362
2.10k
      else
4363
2.10k
  snprintf (buf, size, "%s",
4364
2.10k
      style_imm (styler, "#%" PRIi64, opnd->imm.value));
4365
6.84k
      if (opnd->shifter.operator_present)
4366
6.24k
  {
4367
6.24k
    size_t len = strlen (buf);
4368
6.24k
    const char *shift_name
4369
6.24k
      = aarch64_operand_modifiers[opnd->shifter.kind].name;
4370
6.24k
    snprintf (buf + len, size - len, ", %s %s",
4371
6.24k
        style_sub_mnem (styler, shift_name),
4372
6.24k
        style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
4373
6.24k
  }
4374
6.84k
      break;
4375
4376
19.9k
    case AARCH64_OPND_SVE_PRFOP:
4377
19.9k
      enum_value = opnd->imm.value;
4378
19.9k
      assert (enum_value < ARRAY_SIZE (aarch64_sve_prfop_array));
4379
19.9k
      if (aarch64_sve_prfop_array[enum_value])
4380
12.9k
  snprintf (buf, size, "%s",
4381
12.9k
      style_reg (styler, aarch64_sve_prfop_array[enum_value]));
4382
7.00k
      else
4383
7.00k
  snprintf (buf, size, "%s",
4384
7.00k
      style_imm (styler, "#%" PRIi64, opnd->imm.value));
4385
19.9k
      break;
4386
4387
69.3k
    case AARCH64_OPND_IMM_MOV:
4388
69.3k
      switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
4389
69.3k
  {
4390
10.4k
  case 4: /* e.g. MOV Wd, #<imm32>.  */
4391
10.4k
      {
4392
10.4k
        int imm32 = opnd->imm.value;
4393
10.4k
        snprintf (buf, size, "%s",
4394
10.4k
      style_imm (styler, "#0x%-20x", imm32));
4395
10.4k
        snprintf (comment, comment_size, "#%d", imm32);
4396
10.4k
      }
4397
10.4k
    break;
4398
58.9k
  case 8: /* e.g. MOV Xd, #<imm64>.  */
4399
58.9k
    snprintf (buf, size, "%s", style_imm (styler, "#0x%-20" PRIx64,
4400
58.9k
            opnd->imm.value));
4401
58.9k
    snprintf (comment, comment_size, "#%" PRIi64, opnd->imm.value);
4402
58.9k
    break;
4403
0
  default:
4404
0
    snprintf (buf, size, "<invalid>");
4405
0
    break;
4406
69.3k
  }
4407
69.3k
      break;
4408
4409
69.3k
    case AARCH64_OPND_FPIMM0:
4410
566
      snprintf (buf, size, "%s", style_imm (styler, "#0.0"));
4411
566
      break;
4412
4413
164k
    case AARCH64_OPND_LIMM:
4414
403k
    case AARCH64_OPND_AIMM:
4415
430k
    case AARCH64_OPND_HALF:
4416
430k
    case AARCH64_OPND_SVE_INV_LIMM:
4417
449k
    case AARCH64_OPND_SVE_LIMM:
4418
453k
    case AARCH64_OPND_SVE_LIMM_MOV:
4419
453k
      if (opnd->shifter.amount)
4420
102k
  snprintf (buf, size, "%s, %s %s",
4421
102k
      style_imm (styler, "#0x%" PRIx64, opnd->imm.value),
4422
102k
      style_sub_mnem (styler, "lsl"),
4423
102k
      style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
4424
350k
      else
4425
350k
  snprintf (buf, size, "%s",
4426
350k
      style_imm (styler, "#0x%" PRIx64, opnd->imm.value));
4427
453k
      break;
4428
4429
773
    case AARCH64_OPND_SIMD_IMM:
4430
4.16k
    case AARCH64_OPND_SIMD_IMM_SFT:
4431
4.16k
      if ((! opnd->shifter.amount && opnd->shifter.kind == AARCH64_MOD_LSL)
4432
2.99k
    || opnd->shifter.kind == AARCH64_MOD_NONE)
4433
1.93k
  snprintf (buf, size, "%s",
4434
1.93k
      style_imm (styler, "#0x%" PRIx64, opnd->imm.value));
4435
2.22k
      else
4436
2.22k
  snprintf (buf, size, "%s, %s %s",
4437
2.22k
      style_imm (styler, "#0x%" PRIx64, opnd->imm.value),
4438
2.22k
      style_sub_mnem (styler, aarch64_operand_modifiers[opnd->shifter.kind].name),
4439
2.22k
      style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
4440
4.16k
      break;
4441
4442
1.55k
    case AARCH64_OPND_SVE_AIMM:
4443
9.71k
    case AARCH64_OPND_SVE_ASIMM:
4444
9.71k
      if (opnd->shifter.amount)
4445
186
  snprintf (buf, size, "%s, %s %s",
4446
186
      style_imm (styler, "#%" PRIi64, opnd->imm.value),
4447
186
      style_sub_mnem (styler, "lsl"),
4448
186
      style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
4449
9.52k
      else
4450
9.52k
  snprintf (buf, size, "%s",
4451
9.52k
      style_imm (styler, "#%" PRIi64, opnd->imm.value));
4452
9.71k
      break;
4453
4454
235
    case AARCH64_OPND_FPIMM:
4455
2.31k
    case AARCH64_OPND_SIMD_FPIMM:
4456
3.14k
    case AARCH64_OPND_SVE_FPIMM8:
4457
3.14k
      switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
4458
3.14k
  {
4459
1.88k
  case 2: /* e.g. FMOV <Hd>, #<imm>.  */
4460
1.88k
      {
4461
1.88k
        half_conv_t c;
4462
1.88k
        c.i = expand_fp_imm (2, opnd->imm.value);
4463
1.88k
        snprintf (buf, size, "%s", style_imm (styler, "#%.18e", c.f));
4464
1.88k
      }
4465
1.88k
    break;
4466
604
  case 4: /* e.g. FMOV <Vd>.4S, #<imm>.  */
4467
604
      {
4468
604
        single_conv_t c;
4469
604
        c.i = expand_fp_imm (4, opnd->imm.value);
4470
604
        snprintf (buf, size, "%s", style_imm (styler, "#%.18e", c.f));
4471
604
      }
4472
604
    break;
4473
657
  case 8: /* e.g. FMOV <Sd>, #<imm>.  */
4474
657
      {
4475
657
        double_conv_t c;
4476
657
        c.i = expand_fp_imm (8, opnd->imm.value);
4477
657
        snprintf (buf, size, "%s", style_imm (styler, "#%.18e", c.d));
4478
657
      }
4479
657
    break;
4480
0
  default:
4481
0
    snprintf (buf, size, "<invalid>");
4482
0
    break;
4483
3.14k
  }
4484
3.14k
      break;
4485
4486
3.14k
    case AARCH64_OPND_CCMP_IMM:
4487
12.0k
    case AARCH64_OPND_NZCV:
4488
13.1k
    case AARCH64_OPND_EXCEPTION:
4489
13.4k
    case AARCH64_OPND_UIMM4:
4490
17.9k
    case AARCH64_OPND_UIMM4_ADDG:
4491
17.9k
    case AARCH64_OPND_UIMM7:
4492
22.4k
    case AARCH64_OPND_UIMM10:
4493
22.4k
      if (optional_operand_p (opcode, idx)
4494
304
    && (opnd->imm.value ==
4495
304
        (int64_t) get_optional_operand_default_value (opcode)))
4496
  /* Omit the operand, e.g. DCPS1.  */
4497
74
  break;
4498
22.3k
      snprintf (buf, size, "%s",
4499
22.3k
    style_imm (styler, "#0x%x", (unsigned int) opnd->imm.value));
4500
22.3k
      break;
4501
4502
20.5k
    case AARCH64_OPND_COND:
4503
21.0k
    case AARCH64_OPND_COND1:
4504
21.0k
      snprintf (buf, size, "%s",
4505
21.0k
    style_sub_mnem (styler, opnd->cond->names[0]));
4506
21.0k
      num_conds = ARRAY_SIZE (opnd->cond->names);
4507
41.1k
      for (i = 1; i < num_conds && opnd->cond->names[i]; ++i)
4508
20.0k
  {
4509
20.0k
    size_t len = comment != NULL ? strlen (comment) : 0;
4510
20.0k
    if (i == 1)
4511
13.8k
      snprintf (comment + len, comment_size - len, "%s = %s",
4512
13.8k
          opnd->cond->names[0], opnd->cond->names[i]);
4513
6.24k
    else
4514
6.24k
      snprintf (comment + len, comment_size - len, ", %s",
4515
6.24k
          opnd->cond->names[i]);
4516
20.0k
  }
4517
21.0k
      break;
4518
4519
150k
    case AARCH64_OPND_ADDR_ADRP:
4520
150k
      addr = ((pc + AARCH64_PCREL_OFFSET) & ~(uint64_t)0xfff)
4521
150k
  + opnd->imm.value;
4522
150k
      if (pcrel_p)
4523
150k
  *pcrel_p = 1;
4524
150k
      if (address)
4525
150k
  *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
150k
      snprintf (buf, size, "%s", style_addr (styler, "#0x%" PRIx64 , addr));
4531
150k
      break;
4532
4533
73.2k
    case AARCH64_OPND_ADDR_PCREL9:
4534
236k
    case AARCH64_OPND_ADDR_PCREL14:
4535
697k
    case AARCH64_OPND_ADDR_PCREL19:
4536
1.06M
    case AARCH64_OPND_ADDR_PCREL21:
4537
1.33M
    case AARCH64_OPND_ADDR_PCREL26:
4538
1.33M
      addr = pc + AARCH64_PCREL_OFFSET + opnd->imm.value;
4539
1.33M
      if (pcrel_p)
4540
1.33M
  *pcrel_p = 1;
4541
1.33M
      if (address)
4542
1.33M
  *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.33M
      snprintf (buf, size, "%s", style_addr (styler, "#0x%" PRIx64, addr));
4548
1.33M
      break;
4549
4550
225k
    case AARCH64_OPND_ADDR_SIMPLE:
4551
244k
    case AARCH64_OPND_SIMD_ADDR_SIMPLE:
4552
265k
    case AARCH64_OPND_SIMD_ADDR_POST:
4553
265k
      name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
4554
265k
      if (opnd->type == AARCH64_OPND_SIMD_ADDR_POST)
4555
21.0k
  {
4556
21.0k
    if (opnd->addr.offset.is_reg)
4557
17.8k
      snprintf (buf, size, "[%s], %s",
4558
17.8k
          style_reg (styler, name),
4559
17.8k
          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
21.0k
  }
4565
244k
      else
4566
244k
  snprintf (buf, size, "[%s]", style_reg (styler, name));
4567
265k
      break;
4568
4569
29.4k
    case AARCH64_OPND_ADDR_REGOFF:
4570
42.6k
    case AARCH64_OPND_SVE_ADDR_RR:
4571
50.5k
    case AARCH64_OPND_SVE_ADDR_RR_LSL1:
4572
54.9k
    case AARCH64_OPND_SVE_ADDR_RR_LSL2:
4573
73.9k
    case AARCH64_OPND_SVE_ADDR_RR_LSL3:
4574
93.0k
    case AARCH64_OPND_SVE_ADDR_RR_LSL4:
4575
102k
    case AARCH64_OPND_SVE_ADDR_RM:
4576
106k
    case AARCH64_OPND_SVE_ADDR_RM_LSL1:
4577
111k
    case AARCH64_OPND_SVE_ADDR_RM_LSL2:
4578
115k
    case AARCH64_OPND_SVE_ADDR_RM_LSL3:
4579
115k
    case AARCH64_OPND_SVE_ADDR_RM_LSL4:
4580
131k
    case AARCH64_OPND_SVE_ADDR_RX:
4581
142k
    case AARCH64_OPND_SVE_ADDR_RX_LSL1:
4582
153k
    case AARCH64_OPND_SVE_ADDR_RX_LSL2:
4583
159k
    case AARCH64_OPND_SVE_ADDR_RX_LSL3:
4584
164k
    case AARCH64_OPND_SVE_ADDR_RX_LSL4:
4585
164k
      print_register_offset_address
4586
164k
  (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
4587
164k
   get_offset_int_reg_name (opnd), styler);
4588
164k
      break;
4589
4590
15.7k
    case AARCH64_OPND_SVE_ADDR_ZX:
4591
15.7k
      print_register_offset_address
4592
15.7k
  (buf, size, opnd,
4593
15.7k
   get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier),
4594
15.7k
   get_64bit_int_reg_name (opnd->addr.offset.regno, 0), styler);
4595
15.7k
      break;
4596
4597
25.5k
    case AARCH64_OPND_SVE_ADDR_RZ:
4598
28.7k
    case AARCH64_OPND_SVE_ADDR_RZ_LSL1:
4599
31.2k
    case AARCH64_OPND_SVE_ADDR_RZ_LSL2:
4600
33.9k
    case AARCH64_OPND_SVE_ADDR_RZ_LSL3:
4601
40.4k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW_14:
4602
80.0k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW_22:
4603
81.9k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW1_14:
4604
90.5k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW1_22:
4605
91.6k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW2_14:
4606
98.3k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW2_22:
4607
99.3k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW3_14:
4608
106k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW3_22:
4609
106k
      print_register_offset_address
4610
106k
  (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
4611
106k
   get_addr_sve_reg_name (opnd->addr.offset.regno, opnd->qualifier),
4612
106k
   styler);
4613
106k
      break;
4614
4615
572k
    case AARCH64_OPND_ADDR_SIMM7:
4616
691k
    case AARCH64_OPND_ADDR_SIMM9:
4617
702k
    case AARCH64_OPND_ADDR_SIMM10:
4618
727k
    case AARCH64_OPND_ADDR_SIMM11:
4619
735k
    case AARCH64_OPND_ADDR_SIMM13:
4620
743k
    case AARCH64_OPND_RCPC3_ADDR_OFFSET:
4621
767k
    case AARCH64_OPND_ADDR_OFFSET:
4622
768k
    case AARCH64_OPND_RCPC3_ADDR_OPT_POSTIND:
4623
786k
    case AARCH64_OPND_RCPC3_ADDR_OPT_PREIND_WB:
4624
786k
    case AARCH64_OPND_RCPC3_ADDR_POSTIND:
4625
786k
    case AARCH64_OPND_RCPC3_ADDR_PREIND_WB:
4626
787k
    case AARCH64_OPND_SME_ADDR_RI_U4xVL:
4627
788k
    case AARCH64_OPND_SVE_ADDR_RI_S4x16:
4628
791k
    case AARCH64_OPND_SVE_ADDR_RI_S4x32:
4629
857k
    case AARCH64_OPND_SVE_ADDR_RI_S4xVL:
4630
869k
    case AARCH64_OPND_SVE_ADDR_RI_S4x2xVL:
4631
873k
    case AARCH64_OPND_SVE_ADDR_RI_S4x3xVL:
4632
881k
    case AARCH64_OPND_SVE_ADDR_RI_S4x4xVL:
4633
884k
    case AARCH64_OPND_SVE_ADDR_RI_S6xVL:
4634
889k
    case AARCH64_OPND_SVE_ADDR_RI_S9xVL:
4635
894k
    case AARCH64_OPND_SVE_ADDR_RI_U6:
4636
900k
    case AARCH64_OPND_SVE_ADDR_RI_U6x2:
4637
902k
    case AARCH64_OPND_SVE_ADDR_RI_U6x4:
4638
903k
    case AARCH64_OPND_SVE_ADDR_RI_U6x8:
4639
903k
      print_immediate_offset_address
4640
903k
  (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
4641
903k
   styler);
4642
903k
      break;
4643
4644
5.32k
    case AARCH64_OPND_SVE_ADDR_ZI_U5:
4645
11.5k
    case AARCH64_OPND_SVE_ADDR_ZI_U5x2:
4646
14.5k
    case AARCH64_OPND_SVE_ADDR_ZI_U5x4:
4647
16.1k
    case AARCH64_OPND_SVE_ADDR_ZI_U5x8:
4648
16.1k
      print_immediate_offset_address
4649
16.1k
  (buf, size, opnd,
4650
16.1k
   get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier),
4651
16.1k
   styler);
4652
16.1k
      break;
4653
4654
1.05k
    case AARCH64_OPND_SVE_ADDR_ZZ_LSL:
4655
1.39k
    case AARCH64_OPND_SVE_ADDR_ZZ_SXTW:
4656
2.25k
    case AARCH64_OPND_SVE_ADDR_ZZ_UXTW:
4657
2.25k
      print_register_offset_address
4658
2.25k
  (buf, size, opnd,
4659
2.25k
   get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier),
4660
2.25k
   get_addr_sve_reg_name (opnd->addr.offset.regno, opnd->qualifier),
4661
2.25k
   styler);
4662
2.25k
      break;
4663
4664
248k
    case AARCH64_OPND_ADDR_UIMM12:
4665
248k
      name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
4666
248k
      if (opnd->addr.offset.imm)
4667
233k
  snprintf (buf, size, "[%s, %s]",
4668
233k
      style_reg (styler, name),
4669
233k
      style_imm (styler, "#%d", opnd->addr.offset.imm));
4670
15.0k
      else
4671
15.0k
  snprintf (buf, size, "[%s]", style_reg (styler, name));
4672
248k
      break;
4673
4674
11.6k
    case AARCH64_OPND_SYSREG:
4675
13.5k
    case AARCH64_OPND_SYSREG128:
4676
13.5k
      {
4677
13.5k
  int min_mismatch = 999;
4678
13.5k
  int best_index = -1;
4679
13.5k
  uint32_t op_flags = opnd->sysreg.flags;
4680
21.3M
  for (i = 0; aarch64_sys_regs[i].name; ++i)
4681
21.3M
    {
4682
21.3M
      const aarch64_sys_reg *sr = aarch64_sys_regs + i;
4683
4684
21.3M
      if (!(aarch64_sys_regs[i].value == opnd->sysreg.value)
4685
1.75k
    || aarch64_sys_reg_deprecated_p (aarch64_sys_regs[i].flags)
4686
1.75k
    || aarch64_sys_reg_alias_p (aarch64_sys_regs[i].flags))
4687
21.3M
        continue;
4688
4689
1.75k
      int mismatch_score = 0;
4690
1.75k
      if (!AARCH64_CPU_HAS_ALL_FEATURES (features, sr->features))
4691
906
        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.75k
      if (((sr->flags & F_REG_READ) && (op_flags & F_REG_WRITE))
4695
1.53k
    || ((sr->flags & F_REG_WRITE) && (op_flags & F_REG_READ)))
4696
251
        mismatch_score += 2;
4697
4698
1.75k
      if (mismatch_score < min_mismatch)
4699
1.75k
        {
4700
1.75k
    min_mismatch = mismatch_score;
4701
1.75k
    best_index = i;
4702
1.75k
    if (mismatch_score == 0)
4703
599
      break;
4704
1.75k
        }
4705
1.75k
    }
4706
13.5k
  if (best_index == -1)
4707
11.8k
    {
4708
      /* Use encoding-based name for unrecognised system register.  */
4709
11.8k
      unsigned int value = opnd->sysreg.value;
4710
11.8k
      snprintf (buf, size, "%s",
4711
11.8k
          style_reg (styler, "s%u_%u_c%u_c%u_%u",
4712
11.8k
         (value >> 14) & 0x3, (value >> 11) & 0x7,
4713
11.8k
         (value >> 7) & 0xf, (value >> 3) & 0xf,
4714
11.8k
         value & 0x7));
4715
11.8k
    }
4716
1.73k
  else
4717
1.73k
    {
4718
1.73k
      const aarch64_sys_reg *sr = aarch64_sys_regs + best_index;
4719
1.73k
      snprintf (buf, size, "%s", style_reg (styler, sr->name));
4720
4721
      /* Add a note if we violated read/write constraints.  */
4722
1.73k
      if (notes && min_mismatch)
4723
1.13k
        {
4724
1.13k
    if ((sr->flags & F_REG_READ) && (op_flags & F_REG_WRITE))
4725
206
      *notes = _("writing to a read-only register");
4726
933
    else if ((sr->flags & F_REG_WRITE) && (op_flags & F_REG_READ))
4727
27
      *notes = _("reading from a write-only register");
4728
1.13k
        }
4729
1.73k
    }
4730
13.5k
  break;
4731
11.6k
      }
4732
4733
237
    case AARCH64_OPND_PSTATEFIELD:
4734
945
      for (i = 0; aarch64_pstatefields[i].name; ++i)
4735
945
        if (aarch64_pstatefields[i].value == opnd->pstatefield)
4736
237
          {
4737
            /* PSTATEFIELD name is encoded partially in CRm[3:1] for SVCRSM,
4738
               SVCRZA and SVCRSMZA.  */
4739
237
            uint32_t flags = aarch64_pstatefields[i].flags;
4740
237
            if (flags & F_REG_IN_CRM
4741
0
                && (PSTATE_DECODE_CRM (opnd->sysreg.flags)
4742
0
                    != PSTATE_DECODE_CRM (flags)))
4743
0
              continue;
4744
237
            break;
4745
237
          }
4746
237
      assert (aarch64_pstatefields[i].name);
4747
237
      snprintf (buf, size, "%s",
4748
237
    style_reg (styler, aarch64_pstatefields[i].name));
4749
237
      break;
4750
4751
51
    case AARCH64_OPND_GIC:
4752
51
    case AARCH64_OPND_GICR:
4753
51
    case AARCH64_OPND_GSB:
4754
152
    case AARCH64_OPND_SYSREG_AT:
4755
217
    case AARCH64_OPND_SYSREG_DC:
4756
217
    case AARCH64_OPND_SYSREG_IC:
4757
400
    case AARCH64_OPND_SYSREG_TLBI:
4758
529
    case AARCH64_OPND_SYSREG_TLBIP:
4759
546
    case AARCH64_OPND_SYSREG_PLBI:
4760
546
    case AARCH64_OPND_SYSREG_SR:
4761
546
      snprintf (buf, size, "%s", style_reg (styler, opnd->sysins_op->name));
4762
546
      break;
4763
4764
57
    case AARCH64_OPND_BARRIER:
4765
267
    case AARCH64_OPND_BARRIER_DSB_NXS:
4766
267
      {
4767
267
  if (opnd->barrier->name[0] == '#')
4768
55
    snprintf (buf, size, "%s", style_imm (styler, opnd->barrier->name));
4769
212
  else
4770
212
    snprintf (buf, size, "%s",
4771
212
        style_sub_mnem (styler, opnd->barrier->name));
4772
267
      }
4773
267
      break;
4774
4775
115
    case AARCH64_OPND_BARRIER_ISB:
4776
      /* Operand can be omitted, e.g. in DCPS1.  */
4777
115
      if (! optional_operand_p (opcode, idx)
4778
115
    || (opnd->barrier->value
4779
115
        != get_optional_operand_default_value (opcode)))
4780
10
  snprintf (buf, size, "%s",
4781
10
      style_imm (styler, "#0x%x", opnd->barrier->value));
4782
115
      break;
4783
4784
46.7k
    case AARCH64_OPND_PRFOP:
4785
46.7k
      if ((opnd->prfop->name == NULL)
4786
40.1k
          || (opcode->iclass != ldst_pos && opnd->prfop->value == 0x18))
4787
19.5k
        snprintf (buf, size, "%s",
4788
19.5k
                  style_imm (styler, "#0x%02x", opnd->prfop->value));
4789
27.2k
      else
4790
27.2k
        snprintf (buf, size, "%s", style_sub_mnem (styler, opnd->prfop->name));
4791
46.7k
      break;
4792
4793
869
    case AARCH64_OPND_RPRFMOP:
4794
869
      enum_value = opnd->imm.value;
4795
869
      if (enum_value < ARRAY_SIZE (aarch64_rprfmop_array)
4796
869
    && aarch64_rprfmop_array[enum_value])
4797
127
  snprintf (buf, size, "%s",
4798
127
      style_reg (styler, aarch64_rprfmop_array[enum_value]));
4799
742
      else
4800
742
  snprintf (buf, size, "%s",
4801
742
      style_imm (styler, "#%" PRIi64, opnd->imm.value));
4802
869
      break;
4803
4804
222
    case AARCH64_OPND_BARRIER_PSB:
4805
222
      snprintf (buf, size, "%s", style_sub_mnem (styler, "csync"));
4806
222
      break;
4807
4808
0
    case AARCH64_OPND_X16:
4809
0
      snprintf (buf, size, "%s", style_reg (styler, "x16"));
4810
0
      break;
4811
4812
2.01k
    case AARCH64_OPND_SME_ZT0:
4813
2.01k
      snprintf (buf, size, "%s", style_reg (styler, "zt0"));
4814
2.01k
      break;
4815
4816
92
    case AARCH64_OPND_SME_ZT0_INDEX:
4817
92
      snprintf (buf, size, "%s[%s]", style_reg (styler, "zt0"),
4818
92
    style_imm (styler, "%d", (int) opnd->imm.value));
4819
92
      break;
4820
129
    case AARCH64_OPND_SME_ZT0_INDEX_MUL_VL:
4821
129
      snprintf (buf, size, "%s[%s, %s]", style_reg (styler, "zt0"),
4822
129
    style_imm (styler, "%d", (int) opnd->imm.value),
4823
129
    style_sub_mnem (styler, "mul vl"));
4824
129
      break;
4825
4826
44
    case AARCH64_OPND_SME_ZT0_LIST:
4827
44
      snprintf (buf, size, "{%s}", style_reg (styler, "zt0"));
4828
44
      break;
4829
4830
1
    case AARCH64_OPND_BARRIER_GCSB:
4831
1
      snprintf (buf, size, "%s", style_sub_mnem (styler, "dsync"));
4832
1
      break;
4833
4834
0
    case AARCH64_OPND_NOT_BALANCED_10:
4835
272
    case AARCH64_OPND_NOT_BALANCED_17:
4836
272
      if (opnd->imm.value)
4837
41
  snprintf (buf, size, "%s", style_sub_mnem (styler, "nb"));
4838
272
      break;
4839
4840
203
    case AARCH64_OPND_BTI_TARGET:
4841
203
      snprintf (buf, size, "%s",
4842
203
    style_sub_mnem (styler, opnd->hint_option->name));
4843
203
      break;
4844
4845
146
    case AARCH64_OPND_STSHH_POLICY:
4846
146
      snprintf (buf, size, "%s", style_sub_mnem (styler, opnd->hint_option->name));
4847
146
      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
8.68k
    case AARCH64_OPND_MOPS_ADDR_Rd:
4856
16.1k
    case AARCH64_OPND_MOPS_ADDR_Rs:
4857
16.1k
      snprintf (buf, size, "[%s]!",
4858
16.1k
    style_reg (styler,
4859
16.1k
         get_int_reg_name (opnd->reg.regno,
4860
16.1k
               AARCH64_OPND_QLF_X, 0)));
4861
16.1k
      break;
4862
4863
8.68k
    case AARCH64_OPND_MOPS_WB_Rn:
4864
8.68k
      snprintf (buf, size, "%s!",
4865
8.68k
    style_reg (styler, get_int_reg_name (opnd->reg.regno,
4866
8.68k
                 AARCH64_OPND_QLF_X, 0)));
4867
8.68k
      break;
4868
4869
0
    default:
4870
0
      snprintf (buf, size, "<invalid>");
4871
0
      break;
4872
16.0M
    }
4873
16.0M
}
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.75k
{
4916
1.75k
  return (reg_flags & F_DEPRECATED) != 0;
4917
1.75k
}
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.75k
{
4928
1.75k
  return (reg_flags & F_REG_ALIAS) != 0;
4929
1.75k
}
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.23k
{
5283
1.23k
  return (sys_ins_reg->flags & F_HASXT) != 0;
5284
1.23k
}
5285
5286
bool
5287
aarch64_sys_ins_reg_tlbid_xt (const aarch64_sys_ins_reg *sys_ins_reg)
5288
942
{
5289
942
  return (sys_ins_reg->flags & F_TLBID_XT) != 0;
5290
942
}
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
106k
#define BIT(INSN,BT)     (((INSN) >> (BT)) & 1)
5326
161k
#define BITS(INSN,HI,LO) (((INSN) >> (LO)) & ((1 << (((HI) - (LO)) + 1)) - 1))
5327
5328
static enum err_type
5329
verify_ldpsw (const struct aarch64_inst *inst ATTRIBUTE_UNUSED,
5330
        const aarch64_insn insn, bfd_vma pc ATTRIBUTE_UNUSED,
5331
        bool encoding ATTRIBUTE_UNUSED,
5332
        aarch64_operand_error *mismatch_detail ATTRIBUTE_UNUSED,
5333
        aarch64_instr_sequence *insn_sequence ATTRIBUTE_UNUSED)
5334
53.9k
{
5335
53.9k
  int t  = BITS (insn, 4, 0);
5336
53.9k
  int n  = BITS (insn, 9, 5);
5337
53.9k
  int t2 = BITS (insn, 14, 10);
5338
5339
53.9k
  if (BIT (insn, 23))
5340
15.4k
    {
5341
      /* Write back enabled.  */
5342
15.4k
      if ((t == n || t2 == n) && n != 31)
5343
1.35k
  return ERR_UND;
5344
15.4k
    }
5345
5346
52.5k
  if (BIT (insn, 22))
5347
52.5k
    {
5348
      /* Load */
5349
52.5k
      if (t == t2)
5350
5.32k
  return ERR_UND;
5351
52.5k
    }
5352
5353
47.2k
  return ERR_OK;
5354
52.5k
}
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.20k
{
5365
3.20k
  const aarch64_insn undef_pattern = 0x3;
5366
3.20k
  aarch64_insn value;
5367
5368
3.20k
  assert (inst->opcode);
5369
3.20k
  assert (inst->opcode->operands[2] == AARCH64_OPND_Em);
5370
3.20k
  value = encoding ? inst->value : insn;
5371
3.20k
  assert (value);
5372
5373
3.20k
  if (undef_pattern == extract_fields (value, 0, 2, FLD_sz, FLD_L))
5374
709
    return ERR_UND;
5375
5376
2.49k
  return ERR_OK;
5377
3.20k
}
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
10.0k
{
5392
10.0k
  int rd, rs, rn;
5393
5394
10.0k
  rd = inst->operands[0].reg.regno;
5395
10.0k
  rs = inst->operands[1].reg.regno;
5396
10.0k
  rn = inst->operands[2].reg.regno;
5397
10.0k
  if (rd == rs || rd == rn || rs == rn)
5398
1.46k
    {
5399
1.46k
      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5400
1.46k
      mismatch_detail->error
5401
1.46k
  = _("the three register operands must be distinct from one another");
5402
1.46k
      mismatch_detail->index = -1;
5403
1.46k
      return ERR_UND;
5404
1.46k
    }
5405
5406
8.55k
  return ERR_OK;
5407
10.0k
}
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
213
{
5422
213
  int rd, rn;
5423
5424
213
  rd = inst->operands[0].reg.regno;
5425
213
  rn = inst->operands[1].reg.regno;
5426
213
  if (rd == rn)
5427
80
    {
5428
80
      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5429
80
      mismatch_detail->error
5430
80
  = _("the two register operands must be distinct from each other");
5431
80
      mismatch_detail->index = -1;
5432
80
      return ERR_UND;
5433
80
    }
5434
5435
133
  return ERR_OK;
5436
213
}
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.18k
{
5444
9.18k
  insn_sequence->instr[insn_sequence->num_added_insns++] = *inst;
5445
9.18k
}
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.5k
{
5455
18.5k
  int num_req_entries = 0;
5456
5457
18.5k
  if (insn_sequence->instr)
5458
8.77k
    {
5459
8.77k
      XDELETE (insn_sequence->instr);
5460
8.77k
      insn_sequence->instr = NULL;
5461
8.77k
    }
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.5k
  if (inst && inst->opcode->constraints & C_SCAN_MOVPRFX)
5467
3.93k
    num_req_entries = 1;
5468
18.5k
  if (inst && (inst->opcode->constraints & C_SCAN_MOPS_PME) == C_SCAN_MOPS_P)
5469
4.84k
    num_req_entries = 2;
5470
5471
18.5k
  insn_sequence->num_added_insns = 0;
5472
18.5k
  insn_sequence->num_allocated_insns = num_req_entries;
5473
5474
18.5k
  if (num_req_entries != 0)
5475
8.77k
    {
5476
8.77k
      insn_sequence->instr = XCNEWVEC (aarch64_inst, num_req_entries);
5477
8.77k
      add_insn_to_sequence (inst, insn_sequence);
5478
8.77k
    }
5479
18.5k
}
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
256k
{
5495
256k
  const struct aarch64_opcode *opcode;
5496
256k
  const struct aarch64_inst *prev_insn;
5497
256k
  int i;
5498
5499
256k
  opcode = inst->opcode;
5500
256k
  if (insn_sequence->instr)
5501
8.42k
    prev_insn = insn_sequence->instr + (insn_sequence->num_added_insns - 1);
5502
248k
  else
5503
248k
    prev_insn = NULL;
5504
5505
256k
  if (prev_insn
5506
8.42k
      && (prev_insn->opcode->constraints & C_SCAN_MOPS_PME)
5507
4.55k
      && prev_insn->opcode != opcode - 1)
5508
4.14k
    {
5509
4.14k
      mismatch_detail->kind = AARCH64_OPDE_EXPECTED_A_AFTER_B;
5510
4.14k
      mismatch_detail->error = NULL;
5511
4.14k
      mismatch_detail->index = -1;
5512
4.14k
      mismatch_detail->data[0].s = prev_insn->opcode[1].name;
5513
4.14k
      mismatch_detail->data[1].s = prev_insn->opcode->name;
5514
4.14k
      mismatch_detail->non_fatal = true;
5515
4.14k
      return false;
5516
4.14k
    }
5517
5518
252k
  if (opcode->constraints & C_SCAN_MOPS_PME)
5519
3.83k
    {
5520
3.83k
      if (is_new_section || !prev_insn || prev_insn->opcode != opcode - 1)
5521
3.43k
  {
5522
3.43k
    mismatch_detail->kind = AARCH64_OPDE_A_SHOULD_FOLLOW_B;
5523
3.43k
    mismatch_detail->error = NULL;
5524
3.43k
    mismatch_detail->index = -1;
5525
3.43k
    mismatch_detail->data[0].s = opcode->name;
5526
3.43k
    mismatch_detail->data[1].s = opcode[-1].name;
5527
3.43k
    mismatch_detail->non_fatal = true;
5528
3.43k
    return false;
5529
3.43k
  }
5530
5531
796
      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
738
  if ((opcode->operands[i] == AARCH64_OPND_MOPS_ADDR_Rd
5535
333
       || opcode->operands[i] == AARCH64_OPND_MOPS_ADDR_Rs
5536
160
       || opcode->operands[i] == AARCH64_OPND_MOPS_WB_Rn)
5537
738
      && prev_insn->operands[i].reg.regno != inst->operands[i].reg.regno)
5538
347
    {
5539
347
      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5540
347
      if (opcode->operands[i] == AARCH64_OPND_MOPS_ADDR_Rd)
5541
232
        mismatch_detail->error = _("destination register differs from "
5542
115
           "preceding instruction");
5543
115
      else if (opcode->operands[i] == AARCH64_OPND_MOPS_ADDR_Rs)
5544
13
        mismatch_detail->error = _("source register differs from "
5545
102
           "preceding instruction");
5546
102
      else
5547
102
        mismatch_detail->error = _("size register differs from "
5548
347
           "preceding instruction");
5549
347
      mismatch_detail->index = i;
5550
347
      mismatch_detail->non_fatal = true;
5551
347
      return false;
5552
347
    }
5553
405
    }
5554
5555
248k
  return true;
5556
252k
}
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.18M
{
5578
7.18M
  assert (inst);
5579
7.18M
  assert (inst->opcode);
5580
5581
7.18M
  const struct aarch64_opcode *opcode = inst->opcode;
5582
7.18M
  if (!opcode->constraints && !insn_sequence->instr)
5583
6.91M
    return ERR_OK;
5584
5585
7.18M
  assert (insn_sequence);
5586
5587
265k
  enum err_type res = ERR_OK;
5588
5589
  /* This instruction puts a constraint on the insn_sequence.  */
5590
265k
  if (opcode->flags & F_SCAN)
5591
8.77k
    {
5592
8.77k
      if (insn_sequence->instr)
5593
753
  {
5594
753
    mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5595
753
    mismatch_detail->error = _("instruction opens new dependency "
5596
753
             "sequence without ending previous one");
5597
753
    mismatch_detail->index = -1;
5598
753
    mismatch_detail->non_fatal = true;
5599
753
    res = ERR_VFI;
5600
753
  }
5601
5602
8.77k
      init_insn_sequence (inst, insn_sequence);
5603
8.77k
      return res;
5604
8.77k
    }
5605
5606
265k
  bool is_new_section = (!encoding && pc == 0);
5607
256k
  if (!verify_mops_pme_sequence (inst, is_new_section, mismatch_detail,
5608
256k
         insn_sequence))
5609
7.92k
    {
5610
7.92k
      res = ERR_VFI;
5611
7.92k
      if ((opcode->constraints & C_SCAN_MOPS_PME) != C_SCAN_MOPS_M)
5612
5.90k
  init_insn_sequence (NULL, insn_sequence);
5613
7.92k
    }
5614
5615
  /* Verify constraints on an existing sequence.  */
5616
256k
  if (insn_sequence->instr)
5617
4.29k
    {
5618
4.29k
      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.29k
      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.29k
      if (inst_opcode->constraints & C_SCAN_MOVPRFX)
5635
3.87k
  {
5636
    /* Check to see if the MOVPRFX SVE instruction is followed by an SVE
5637
       instruction for better error messages.  */
5638
3.87k
    bool sve_operand_p = false;
5639
13.8k
    for (int i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
5640
12.4k
      {
5641
12.4k
        enum aarch64_operand_class op_class
5642
12.4k
    = aarch64_get_operand_class (opcode->operands[i]);
5643
12.4k
        if (op_class == AARCH64_OPND_CLASS_SVE_REG
5644
10.6k
      || op_class == AARCH64_OPND_CLASS_SVE_REGLIST
5645
10.2k
      || op_class == AARCH64_OPND_CLASS_PRED_REG)
5646
2.45k
    {
5647
2.45k
      sve_operand_p = true;
5648
2.45k
      break;
5649
2.45k
    }
5650
12.4k
      }
5651
5652
3.87k
    if (!sve_operand_p)
5653
1.42k
      {
5654
1.42k
        mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5655
1.42k
        mismatch_detail->error = _("SVE instruction expected after "
5656
1.42k
           "`movprfx'");
5657
1.42k
        mismatch_detail->index = -1;
5658
1.42k
        mismatch_detail->non_fatal = true;
5659
1.42k
        res = ERR_VFI;
5660
1.42k
        goto done;
5661
1.42k
      }
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.45k
    if (!(opcode->constraints & C_SCAN_MOVPRFX))
5666
855
      {
5667
855
        mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5668
855
        mismatch_detail->error = _("SVE `movprfx' compatible instruction "
5669
855
           "expected");
5670
855
        mismatch_detail->index = -1;
5671
855
        mismatch_detail->non_fatal = true;
5672
855
        res = ERR_VFI;
5673
855
        goto done;
5674
855
      }
5675
5676
    /* Next check for usage of the predicate register.  */
5677
1.60k
    aarch64_opnd_info blk_dest = insn_sequence->instr->operands[0];
5678
1.60k
    aarch64_opnd_info blk_pred, inst_pred;
5679
1.60k
    memset (&blk_pred, 0, sizeof (aarch64_opnd_info));
5680
1.60k
    memset (&inst_pred, 0, sizeof (aarch64_opnd_info));
5681
1.60k
    bool predicated = false;
5682
1.60k
    assert (blk_dest.type == AARCH64_OPND_SVE_Zd);
5683
5684
    /* Determine if the movprfx instruction used is predicated or not.  */
5685
1.60k
    if (insn_sequence->instr->operands[1].type == AARCH64_OPND_SVE_Pg3)
5686
1.48k
      {
5687
1.48k
        predicated = true;
5688
1.48k
        blk_pred = insn_sequence->instr->operands[1];
5689
1.48k
      }
5690
5691
1.60k
    unsigned char max_elem_size = 0;
5692
1.60k
    unsigned char current_elem_size;
5693
1.60k
    int num_op_used = 0, last_op_usage = 0;
5694
1.60k
    int i, inst_pred_idx = -1;
5695
1.60k
    int num_ops = aarch64_num_of_operands (opcode);
5696
7.21k
    for (i = 0; i < num_ops; i++)
5697
5.61k
      {
5698
5.61k
        aarch64_opnd_info inst_op = inst->operands[i];
5699
5.61k
        switch (inst_op.type)
5700
5.61k
    {
5701
1.97k
      case AARCH64_OPND_SVE_Zd:
5702
2.62k
      case AARCH64_OPND_SVE_Zm_5:
5703
2.80k
      case AARCH64_OPND_SVE_Zm_16:
5704
3.38k
      case AARCH64_OPND_SVE_Zn:
5705
3.38k
      case AARCH64_OPND_SVE_Zt:
5706
3.44k
      case AARCH64_OPND_SVE_Vm:
5707
3.53k
      case AARCH64_OPND_SVE_Vn:
5708
3.53k
      case AARCH64_OPND_Va:
5709
3.53k
      case AARCH64_OPND_Vn:
5710
3.53k
      case AARCH64_OPND_Vm:
5711
3.53k
      case AARCH64_OPND_Sn:
5712
3.53k
      case AARCH64_OPND_Sm:
5713
3.53k
        if (inst_op.reg.regno == blk_dest.reg.regno)
5714
840
          {
5715
840
      num_op_used++;
5716
840
      last_op_usage = i;
5717
840
          }
5718
3.53k
        current_elem_size
5719
3.53k
          = aarch64_get_qualifier_esize (inst_op.qualifier);
5720
3.53k
        if (current_elem_size > max_elem_size)
5721
1.60k
          max_elem_size = current_elem_size;
5722
3.53k
        break;
5723
0
      case AARCH64_OPND_SVE_Pd:
5724
1.04k
      case AARCH64_OPND_SVE_Pg3:
5725
1.04k
      case AARCH64_OPND_SVE_Pg4_5:
5726
1.04k
      case AARCH64_OPND_SVE_Pg4_10:
5727
1.24k
      case AARCH64_OPND_SVE_Pg4_16:
5728
1.24k
      case AARCH64_OPND_SVE_Pm:
5729
1.24k
      case AARCH64_OPND_SVE_Pn:
5730
1.24k
      case AARCH64_OPND_SVE_Pt:
5731
1.24k
      case AARCH64_OPND_SME_Pm:
5732
1.24k
        inst_pred = inst_op;
5733
1.24k
        inst_pred_idx = i;
5734
1.24k
        break;
5735
837
      default:
5736
837
        break;
5737
5.61k
    }
5738
5.61k
      }
5739
5740
1.60k
     assert (max_elem_size != 0);
5741
1.60k
     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.60k
     current_elem_size
5745
1.60k
       = opcode->constraints & C_MAX_ELEM
5746
1.60k
         ? max_elem_size
5747
1.60k
         : aarch64_get_qualifier_esize (inst_dest.qualifier);
5748
5749
    /* If movprfx is predicated do some extra checks.  */
5750
1.60k
    if (predicated)
5751
1.48k
      {
5752
        /* The instruction must be predicated.  */
5753
1.48k
        if (inst_pred_idx < 0)
5754
361
    {
5755
361
      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5756
361
      mismatch_detail->error = _("predicated instruction expected "
5757
361
               "after `movprfx'");
5758
361
      mismatch_detail->index = -1;
5759
361
      mismatch_detail->non_fatal = true;
5760
361
      res = ERR_VFI;
5761
361
      goto done;
5762
361
    }
5763
5764
        /* The instruction must have a merging predicate.  */
5765
1.12k
        if (inst_pred.qualifier != AARCH64_OPND_QLF_P_M)
5766
34
    {
5767
34
      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5768
34
      mismatch_detail->error = _("merging predicate expected due "
5769
34
               "to preceding `movprfx'");
5770
34
      mismatch_detail->index = inst_pred_idx;
5771
34
      mismatch_detail->non_fatal = true;
5772
34
      res = ERR_VFI;
5773
34
      goto done;
5774
34
    }
5775
5776
        /* The same register must be used in instruction.  */
5777
1.08k
        if (blk_pred.reg.regno != inst_pred.reg.regno)
5778
614
    {
5779
614
      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5780
614
      mismatch_detail->error = _("predicate register differs "
5781
614
               "from that in preceding "
5782
614
               "`movprfx'");
5783
614
      mismatch_detail->index = inst_pred_idx;
5784
614
      mismatch_detail->non_fatal = true;
5785
614
      res = ERR_VFI;
5786
614
      goto done;
5787
614
    }
5788
1.08k
      }
5789
5790
    /* Destructive operations by definition must allow one usage of the
5791
       same register.  */
5792
593
    int allowed_usage
5793
593
      = aarch64_is_destructive_by_operands (opcode) ? 2 : 1;
5794
5795
    /* Operand is not used at all.  */
5796
593
    if (num_op_used == 0)
5797
133
      {
5798
133
        mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5799
133
        mismatch_detail->error = _("output register of preceding "
5800
133
           "`movprfx' not used in current "
5801
133
           "instruction");
5802
133
        mismatch_detail->index = 0;
5803
133
        mismatch_detail->non_fatal = true;
5804
133
        res = ERR_VFI;
5805
133
        goto done;
5806
133
      }
5807
5808
    /* We now know it's used, now determine exactly where it's used.  */
5809
460
    if (blk_dest.reg.regno != inst_dest.reg.regno)
5810
72
      {
5811
72
        mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5812
72
        mismatch_detail->error = _("output register of preceding "
5813
72
           "`movprfx' expected as output");
5814
72
        mismatch_detail->index = 0;
5815
72
        mismatch_detail->non_fatal = true;
5816
72
        res = ERR_VFI;
5817
72
        goto done;
5818
72
      }
5819
5820
    /* Operand used more than allowed for the specific opcode type.  */
5821
388
    if (num_op_used > allowed_usage)
5822
120
      {
5823
120
        mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5824
120
        mismatch_detail->error = _("output register of preceding "
5825
120
           "`movprfx' used as input");
5826
120
        mismatch_detail->index = last_op_usage;
5827
120
        mismatch_detail->non_fatal = true;
5828
120
        res = ERR_VFI;
5829
120
        goto done;
5830
120
      }
5831
5832
    /* Now the only thing left is the qualifiers checks.  The register
5833
       must have the same maximum element size.  */
5834
268
    if (inst_dest.qualifier != AARCH64_OPND_QLF_NIL
5835
268
        && blk_dest.qualifier != AARCH64_OPND_QLF_NIL
5836
154
        && current_elem_size
5837
154
     != aarch64_get_qualifier_esize (blk_dest.qualifier))
5838
40
      {
5839
40
        mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5840
40
        mismatch_detail->error = _("register size not compatible with "
5841
40
           "previous `movprfx'");
5842
40
        mismatch_detail->index = 0;
5843
40
        mismatch_detail->non_fatal = true;
5844
40
        res = ERR_VFI;
5845
40
        goto done;
5846
40
      }
5847
268
  }
5848
5849
4.29k
    done:
5850
4.29k
      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.88k
  init_insn_sequence (NULL, insn_sequence);
5854
410
      else
5855
410
  add_insn_to_sequence (inst, insn_sequence);
5856
4.29k
    }
5857
5858
256k
  return res;
5859
256k
}
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.90k
{
5869
8.90k
  int64_t svalue = uvalue;
5870
8.90k
  uint64_t upper = (uint64_t) -1 << (esize * 4) << (esize * 4);
5871
5872
8.90k
  if ((uvalue & ~upper) != uvalue && (uvalue | upper) != uvalue)
5873
0
    return false;
5874
8.90k
  if (esize <= 4 || (uint32_t) uvalue == (uint32_t) (uvalue >> 32))
5875
7.39k
    {
5876
7.39k
      svalue = (int32_t) uvalue;
5877
7.39k
      if (esize <= 2 || (uint16_t) uvalue == (uint16_t) (uvalue >> 16))
5878
2.01k
  {
5879
2.01k
    svalue = (int16_t) uvalue;
5880
2.01k
    if (esize == 1 || (uint8_t) uvalue == (uint8_t) (uvalue >> 8))
5881
979
      return false;
5882
2.01k
  }
5883
7.39k
    }
5884
7.92k
  if ((svalue & 0xff) == 0)
5885
3.37k
    svalue /= 256;
5886
7.92k
  return svalue < -128 || svalue >= 128;
5887
8.90k
}
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"