Coverage Report

Created: 2026-07-12 09:22

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
743k
{
132
743k
  return (qualifier >= AARCH64_OPND_QLF_V_8B
133
593k
    && qualifier <= AARCH64_OPND_QLF_V_1Q);
134
743k
}
135
136
static inline bool
137
fp_qualifier_p (enum aarch64_opnd_qualifier qualifier)
138
1.00k
{
139
1.00k
  return (qualifier >= AARCH64_OPND_QLF_S_B
140
1.00k
    && qualifier <= AARCH64_OPND_QLF_S_Q);
141
1.00k
}
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
321k
{
169
321k
  if (vector_qualifier_p (qualifiers[0]))
170
320k
    {
171
      /* e.g. v.4s, v.4s, v.4s
172
     or v.4h, v.4h, v.h[3].  */
173
320k
      if (qualifiers[0] == qualifiers[1]
174
152k
    && vector_qualifier_p (qualifiers[2])
175
107k
    && (aarch64_get_qualifier_esize (qualifiers[0])
176
107k
        == aarch64_get_qualifier_esize (qualifiers[2])))
177
102k
  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
218k
      if (vector_qualifier_p (qualifiers[1])
182
156k
    && aarch64_get_qualifier_esize (qualifiers[0]) != 0
183
156k
    && (aarch64_get_qualifier_esize (qualifiers[0])
184
156k
        == aarch64_get_qualifier_esize (qualifiers[1]) << 1))
185
56.4k
  return DP_VECTOR_LONG;
186
      /* e.g. v.8h, v.8h, v.8b.  */
187
162k
      if (qualifiers[0] == qualifiers[1]
188
49.8k
    && vector_qualifier_p (qualifiers[2])
189
5.19k
    && aarch64_get_qualifier_esize (qualifiers[0]) != 0
190
5.19k
    && (aarch64_get_qualifier_esize (qualifiers[0])
191
5.19k
        == aarch64_get_qualifier_esize (qualifiers[2]) << 1))
192
5.19k
  return DP_VECTOR_WIDE;
193
162k
    }
194
1.00k
  else if (fp_qualifier_p (qualifiers[0]))
195
1.00k
    {
196
      /* e.g. SADDLV <V><d>, <Vn>.<T>.  */
197
1.00k
      if (vector_qualifier_p (qualifiers[1])
198
814
    && (qualifiers[2] == AARCH64_OPND_QLF_UNUSED))
199
814
  return DP_VECTOR_ACROSS_LANES;
200
1.00k
    }
201
202
157k
  return DP_UNKNOWN;
203
321k
}
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
321k
{
216
321k
  return
217
321k
    significant_operand_index [get_data_pattern (opcode->qualifiers_list[0])];
218
321k
}
219

220
enum aarch64_operand_class
221
aarch64_get_operand_class (enum aarch64_opnd type)
222
2.59M
{
223
2.59M
  return aarch64_operands[type].op_class;
224
2.59M
}
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
63.5k
{
264
63.5k
  assert (value < 16);
265
63.5k
  return &aarch64_conds[(unsigned int) value];
266
63.5k
}
267
268
const aarch64_cond *
269
get_inverted_cond (const aarch64_cond *cond)
270
406
{
271
406
  return &aarch64_conds[cond->value ^ 0x1];
272
406
}
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
605k
{
316
605k
  if (extend_p)
317
111k
    return AARCH64_MOD_UXTB + value;
318
494k
  else
319
494k
    return AARCH64_MOD_LSL - value;
320
605k
}
321
322
bool
323
aarch64_extend_operator_p (enum aarch64_modifier_kind kind)
324
47.4k
{
325
47.4k
  return kind > AARCH64_MOD_LSL && kind <= AARCH64_MOD_SXTX;
326
47.4k
}
327
328
static inline bool
329
aarch64_shift_operator_p (enum aarch64_modifier_kind kind)
330
472k
{
331
472k
  return kind >= AARCH64_MOD_ROR && kind <= AARCH64_MOD_LSL;
332
472k
}
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
2.74M
{
433
2.74M
  return (low <= value) && (value <= high);
434
2.74M
}
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
1.84M
{
440
1.84M
  return (value % align) == 0;
441
1.84M
}
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.18M
{
447
1.18M
  assert (width < 32);
448
1.18M
  if (width < sizeof (value) * 8)
449
1.18M
    {
450
1.18M
      int64_t lim = (uint64_t) 1 << (width - 1);
451
1.18M
      if (value >= -lim && value < lim)
452
1.18M
  return true;
453
1.18M
    }
454
0
  return false;
455
1.18M
}
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.16M
{
461
2.16M
  assert (width < 32);
462
2.16M
  if (width < sizeof (value) * 8)
463
2.16M
    {
464
2.16M
      int64_t lim = (uint64_t) 1 << width;
465
2.16M
      if (value >= 0 && value < lim)
466
2.16M
  return true;
467
2.16M
    }
468
0
  return false;
469
2.16M
}
470
471
/* Return true if OPERAND is SP or WSP.  */
472
bool
473
aarch64_stack_pointer_p (const aarch64_opnd_info *operand)
474
147k
{
475
147k
  return ((aarch64_get_operand_class (operand->type)
476
147k
     == AARCH64_OPND_CLASS_INT_REG)
477
147k
    && operand_maybe_stack_pointer (aarch64_operands + operand->type)
478
96.0k
    && operand->reg.regno == 31);
479
147k
}
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
10.9M
{
581
10.9M
  return aarch64_opnd_qualifiers[qualifier].kind == OQK_OPD_VARIANT;
582
10.9M
}
583
584
static inline bool
585
qualifier_value_in_range_constraint_p (aarch64_opnd_qualifier_t qualifier)
586
3.93M
{
587
3.93M
  return aarch64_opnd_qualifiers[qualifier].kind == OQK_VALUE_IN_RANGE;
588
3.93M
}
589
590
const char*
591
aarch64_get_qualifier_name (aarch64_opnd_qualifier_t qualifier)
592
4.22M
{
593
4.22M
  return aarch64_opnd_qualifiers[qualifier].desc;
594
4.22M
}
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
7.83M
{
601
7.83M
  assert (operand_variant_qualifier_p (qualifier));
602
7.83M
  return aarch64_opnd_qualifiers[qualifier].data0;
603
7.83M
}
604
605
unsigned char
606
aarch64_get_qualifier_nelem (aarch64_opnd_qualifier_t qualifier)
607
102k
{
608
102k
  assert (operand_variant_qualifier_p (qualifier));
609
102k
  return aarch64_opnd_qualifiers[qualifier].data1;
610
102k
}
611
612
aarch64_insn
613
aarch64_get_qualifier_standard_value (aarch64_opnd_qualifier_t qualifier)
614
3.00M
{
615
3.00M
  assert (operand_variant_qualifier_p (qualifier));
616
3.00M
  return aarch64_opnd_qualifiers[qualifier].data2;
617
3.00M
}
618
619
static int
620
get_lower_bound (aarch64_opnd_qualifier_t qualifier)
621
424k
{
622
424k
  assert (qualifier_value_in_range_constraint_p (qualifier));
623
424k
  return aarch64_opnd_qualifiers[qualifier].data0;
624
424k
}
625
626
static int
627
get_upper_bound (aarch64_opnd_qualifier_t qualifier)
628
453k
{
629
453k
  assert (qualifier_value_in_range_constraint_p (qualifier));
630
453k
  return aarch64_opnd_qualifiers[qualifier].data1;
631
453k
}
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
689
{
677
689
  int i = 0;
678
689
  const enum aarch64_opnd *opnds = opcode->operands;
679
680
689
  if (opnds[0] == AARCH64_OPND_NIL)
681
0
    return false;
682
683
2.08k
  while (opnds[++i] != AARCH64_OPND_NIL)
684
1.73k
    if (opnds[i] == opnds[0])
685
337
      return true;
686
687
352
  return false;
688
689
}
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
9.11M
{
696
9.11M
  int i = 0;
697
9.11M
  const enum aarch64_opnd *opnds = opcode->operands;
698
31.3M
  while (opnds[i++] != AARCH64_OPND_NIL)
699
22.2M
    ;
700
9.11M
  --i;
701
9.11M
  assert (i >= 0 && i <= AARCH64_MAX_OPND_NUM);
702
9.11M
  return i;
703
9.11M
}
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
8.20M
{
736
8.20M
  int i, num_opnds, invalid, min_invalid;
737
8.20M
  const aarch64_opnd_qualifier_t *qualifiers;
738
739
8.20M
  num_opnds = aarch64_num_of_operands (inst->opcode);
740
8.20M
  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
8.20M
  if (stop_at < 0 || stop_at >= num_opnds)
748
7.15M
    stop_at = num_opnds - 1;
749
750
  /* For each pattern.  */
751
8.20M
  min_invalid = num_opnds;
752
11.3M
  for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i, ++qualifiers_list)
753
11.3M
    {
754
11.3M
      int j;
755
11.3M
      qualifiers = *qualifiers_list;
756
757
      /* Start as positive.  */
758
11.3M
      invalid = 0;
759
760
11.3M
      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
11.3M
      if (i > 0 && empty_qualifier_sequence_p (qualifiers))
770
65.5k
  break;
771
772
39.1M
      for (j = 0; j < num_opnds && j <= stop_at; ++j, ++qualifiers)
773
27.8M
  if (inst->operands[j].qualifier != *qualifiers
774
18.9M
       && inst->operands[j].qualifier != AARCH64_OPND_QLF_UNKNOWN)
775
4.40M
    invalid += 1;
776
777
11.2M
      if (min_invalid > invalid)
778
9.95M
  min_invalid = invalid;
779
780
      /* Qualifiers established.  */
781
11.2M
      if (min_invalid == 0)
782
8.14M
  break;
783
11.2M
    }
784
785
8.20M
  *invalid_count = min_invalid;
786
8.20M
  if (min_invalid == 0)
787
8.14M
    {
788
      /* Fill the result in *RET.  */
789
8.14M
      int j;
790
8.14M
      qualifiers = *qualifiers_list;
791
792
8.14M
      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
27.4M
      for (j = 0; j <= stop_at; ++j, ++qualifiers)
799
19.3M
  ret[j] = *qualifiers;
800
45.8M
      for (; j < AARCH64_MAX_OPND_NUM; ++j)
801
37.6M
  ret[j] = AARCH64_OPND_QLF_UNKNOWN;
802
803
8.14M
      DEBUG_TRACE ("SUCCESS");
804
8.14M
      return 1;
805
8.14M
    }
806
807
65.5k
  DEBUG_TRACE ("FAIL");
808
65.5k
  return 0;
809
8.20M
}
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
7.15M
{
826
7.15M
  int i;
827
7.15M
  aarch64_opnd_qualifier_seq_t qualifiers;
828
829
7.15M
  if (!aarch64_find_best_match (inst, inst->opcode->qualifiers_list, -1,
830
7.15M
        qualifiers, invalid_count))
831
39.1k
    {
832
39.1k
      DEBUG_TRACE ("matching FAIL");
833
39.1k
      return 0;
834
39.1k
    }
835
836
  /* Update the qualifiers.  */
837
7.11M
  if (update_p)
838
23.7M
    for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
839
23.7M
      {
840
23.7M
  if (inst->opcode->operands[i] == AARCH64_OPND_NIL)
841
7.11M
    break;
842
16.6M
  DEBUG_TRACE_IF (inst->operands[i].qualifier != qualifiers[i],
843
16.6M
      "update %s with %s for operand %d",
844
16.6M
      aarch64_get_qualifier_name (inst->operands[i].qualifier),
845
16.6M
      aarch64_get_qualifier_name (qualifiers[i]), i);
846
16.6M
  inst->operands[i].qualifier = qualifiers[i];
847
16.6M
      }
848
849
7.11M
  DEBUG_TRACE ("matching SUCCESS");
850
7.11M
  return 1;
851
7.15M
}
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
85.1k
{
863
85.1k
  int amount;
864
865
85.1k
  DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 ")", value, value);
866
867
85.1k
  if (is32)
868
14.9k
    {
869
      /* Allow all zeros or all ones in top 32-bits, so that
870
   32-bit constant expressions like ~0x80000000 are
871
   permitted.  */
872
14.9k
      if (value >> 32 != 0 && value >> 32 != 0xffffffff)
873
  /* Immediate out of range.  */
874
0
  return false;
875
14.9k
      value &= 0xffffffff;
876
14.9k
    }
877
878
  /* first, try movz then movn */
879
85.1k
  amount = -1;
880
85.1k
  if ((value & ((uint64_t) 0xffff << 0)) == value)
881
21.3k
    amount = 0;
882
63.7k
  else if ((value & ((uint64_t) 0xffff << 16)) == value)
883
9.98k
    amount = 16;
884
53.7k
  else if (!is32 && (value & ((uint64_t) 0xffff << 32)) == value)
885
18.2k
    amount = 32;
886
35.4k
  else if (!is32 && (value & ((uint64_t) 0xffff << 48)) == value)
887
5.22k
    amount = 48;
888
889
85.1k
  if (amount == -1)
890
30.2k
    {
891
30.2k
      DEBUG_TRACE ("exit false with 0x%" PRIx64 "(%" PRIi64 ")", value, value);
892
30.2k
      return false;
893
30.2k
    }
894
895
54.8k
  if (shift_amount != NULL)
896
0
    *shift_amount = amount;
897
898
54.8k
  DEBUG_TRACE ("exit true with amount %d", amount);
899
900
54.8k
  return true;
901
85.1k
}
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
309k
#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
3.66M
{
935
3.66M
  const simd_imm_encoding *imm1 = (const simd_imm_encoding *)i1;
936
3.66M
  const simd_imm_encoding *imm2 = (const simd_imm_encoding *)i2;
937
938
3.66M
  if (imm1->imm < imm2->imm)
939
1.83M
    return -1;
940
1.83M
  if (imm1->imm > imm2->imm)
941
1.52M
    return +1;
942
309k
  return 0;
943
1.83M
}
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
309k
{
1036
309k
  simd_imm_encoding imm_enc;
1037
309k
  const simd_imm_encoding *imm_encoding;
1038
309k
  static bool initialized = false;
1039
309k
  uint64_t upper;
1040
309k
  int i;
1041
1042
309k
  DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 "), esize: %d", value,
1043
309k
         value, esize);
1044
1045
309k
  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
309k
  upper = (uint64_t) -1 << (esize * 4) << (esize * 4);
1054
309k
  if ((value & ~upper) != value && (value | upper) != value)
1055
0
    return false;
1056
1057
  /* Replicate to a full 64-bit value.  */
1058
309k
  value &= ~upper;
1059
534k
  for (i = esize * 8; i < 64; i *= 2)
1060
225k
    value |= (value << i);
1061
1062
309k
  imm_enc.imm = value;
1063
309k
  imm_encoding = (const simd_imm_encoding *)
1064
309k
    bsearch(&imm_enc, simd_immediates, TOTAL_IMM_NB,
1065
309k
            sizeof(simd_immediates[0]), simd_imm_encoding_cmp);
1066
309k
  if (imm_encoding == NULL)
1067
0
    {
1068
0
      DEBUG_TRACE ("exit with false");
1069
0
      return false;
1070
0
    }
1071
309k
  if (encoding != NULL)
1072
0
    *encoding = imm_encoding->encoding;
1073
309k
  DEBUG_TRACE ("exit with true");
1074
309k
  return true;
1075
309k
}
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
853
{
1084
853
  int i, ret;
1085
853
  uint32_t byte;
1086
1087
853
  ret = 0;
1088
7.67k
  for (i = 0; i < 8; i++)
1089
6.82k
    {
1090
6.82k
      byte = (imm >> (8 * i)) & 0xff;
1091
6.82k
      if (byte == 0xff)
1092
3.92k
  ret |= 1 << i;
1093
2.89k
      else if (byte != 0x00)
1094
0
  return -1;
1095
6.82k
    }
1096
853
  return ret;
1097
853
}
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
2.73k
{
1117
2.73k
  if (mismatch_detail == NULL)
1118
2.73k
    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
41.3k
{
1150
41.3k
  if (mismatch_detail == NULL)
1151
41.3k
    return;
1152
0
  set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1153
0
        _("immediate value"));
1154
0
}
1155
1156
static inline void
1157
set_offset_out_of_range_error (aarch64_operand_error *mismatch_detail,
1158
             int idx, int lower_bound, int upper_bound)
1159
0
{
1160
0
  if (mismatch_detail == NULL)
1161
0
    return;
1162
0
  set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1163
0
        _("immediate offset"));
1164
0
}
1165
1166
static inline void
1167
set_regno_out_of_range_error (aarch64_operand_error *mismatch_detail,
1168
            int idx, int lower_bound, int upper_bound)
1169
0
{
1170
0
  if (mismatch_detail == NULL)
1171
0
    return;
1172
0
  set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
1173
0
        _("register number"));
1174
0
}
1175
1176
static inline void
1177
set_elem_idx_out_of_range_error (aarch64_operand_error *mismatch_detail,
1178
         int idx, int lower_bound, int upper_bound)
1179
673
{
1180
673
  if (mismatch_detail == NULL)
1181
673
    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
84.4k
{
1190
84.4k
  if (mismatch_detail == NULL)
1191
84.4k
    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
676
{
1222
676
  if (mismatch_detail == NULL)
1223
676
    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
43.5k
{
1252
43.5k
  if (mismatch_detail == NULL)
1253
43.5k
    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
81.8k
{
1267
81.8k
  if (!value_in_range_p (opnd->reglane.regno, min_regno, max_regno))
1268
0
    {
1269
0
      set_invalid_regno_error (mismatch_detail, idx, prefix, min_regno,
1270
0
             max_regno);
1271
0
      return false;
1272
0
    }
1273
81.8k
  if (!value_in_range_p (opnd->reglane.index, min_index, max_index))
1274
0
    {
1275
0
      set_elem_idx_out_of_range_error (mismatch_detail, idx, min_index,
1276
0
               max_index);
1277
0
      return false;
1278
0
    }
1279
81.8k
  return true;
1280
81.8k
}
1281
1282
/* Check that register list operand OPND has NUM_REGS registers and a
1283
   register stride of STRIDE.  */
1284
1285
static bool
1286
check_reglist (const aarch64_opnd_info *opnd,
1287
         aarch64_operand_error *mismatch_detail, int idx,
1288
         int num_regs, int stride)
1289
357k
{
1290
357k
  if (opnd->reglist.num_regs != num_regs)
1291
676
    {
1292
676
      set_reg_list_length_error (mismatch_detail, idx, num_regs);
1293
676
      return false;
1294
676
    }
1295
356k
  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
356k
  return true;
1301
356k
}
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.17M
{
1335
1.17M
  const aarch64_operand *operand = get_operand_from_code (type);
1336
1.17M
  uint8_t size = get_operand_fields_width (operand);
1337
1.17M
  bool unsigned_imm = operand_need_unsigned_offset (operand);
1338
1.17M
  bool (*value_fit_field) (int64_t, unsigned)
1339
1.17M
    = (unsigned_imm
1340
1.17M
      ? value_fit_unsigned_field_p
1341
1.17M
      : value_fit_signed_field_p);
1342
1343
1.17M
  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.17M
  return true;
1350
1.17M
}
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
177k
{
1370
177k
  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
177k
  int max_index = max_value * range_size;
1386
177k
  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
177k
  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
177k
  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
177k
  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
177k
  return true;
1428
177k
}
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
17.8k
{
1436
17.8k
  unsigned num_bytes = 0; /* total number of bytes transferred.  */
1437
17.8k
  enum aarch64_operand_class opnd_class;
1438
17.8k
  enum aarch64_opnd type;
1439
1440
52.9k
  for (int i = 0; i < AARCH64_MAX_OPND_NUM; i++)
1441
52.9k
    {
1442
52.9k
      type = opnds[i].type;
1443
52.9k
      opnd_class = aarch64_operands[type].op_class;
1444
52.9k
      if (opnd_class == AARCH64_OPND_CLASS_ADDRESS)
1445
17.8k
  break;
1446
35.0k
      num_bytes += aarch64_get_qualifier_esize (opnds[i].qualifier);
1447
35.0k
    }
1448
17.8k
  return num_bytes;
1449
17.8k
}
1450
1451
1452
/* General constraint checking based on operand code.
1453
1454
   Return 1 if OPNDS[IDX] meets the general constraint of operand code TYPE
1455
   as the IDXth operand of opcode OPCODE.  Otherwise return 0.
1456
1457
   This function has to be called after the qualifiers for all operands
1458
   have been resolved.
1459
1460
   Mismatching error message is returned in *MISMATCH_DETAIL upon request,
1461
   i.e. when MISMATCH_DETAIL is non-NULL.  This avoids the generation
1462
   of error message during the disassembling where error message is not
1463
   wanted.  We avoid the dynamic construction of strings of error messages
1464
   here (i.e. in libopcodes), as it is costly and complicated; instead, we
1465
   use a combination of error code, static string and some integer data to
1466
   represent an error.  */
1467
1468
static bool
1469
operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
1470
          enum aarch64_opnd type,
1471
          const aarch64_opcode *opcode,
1472
          aarch64_operand_error *mismatch_detail)
1473
16.5M
{
1474
16.5M
  unsigned num, modifiers, shift;
1475
16.5M
  unsigned char size;
1476
16.5M
  int64_t imm, min_value, max_value;
1477
16.5M
  uint64_t uvalue, mask;
1478
16.5M
  const aarch64_opnd_info *opnd = opnds + idx;
1479
16.5M
  aarch64_opnd_qualifier_t qualifier = opnd->qualifier;
1480
16.5M
  int i;
1481
1482
16.5M
  assert (opcode->operands[idx] == opnd->type && opnd->type == type);
1483
1484
16.5M
  switch (aarch64_operands[type].op_class)
1485
16.5M
    {
1486
5.37M
    case AARCH64_OPND_CLASS_INT_REG:
1487
      /* Check for pair of xzr registers.  */
1488
5.37M
      if (type == AARCH64_OPND_PAIRREG_OR_XZR
1489
3.38k
    && opnds[idx - 1].reg.regno == 0x1f)
1490
1.63k
  {
1491
1.63k
    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.63k
  }
1499
      /* Check pair reg constraints for instructions taking a pair of
1500
   consecutively-numbered general-purpose registers.  */
1501
5.37M
      else if (type == AARCH64_OPND_PAIRREG
1502
5.36M
         || type == AARCH64_OPND_PAIRREG_OR_XZR)
1503
7.38k
  {
1504
7.38k
    assert (idx == 1 || idx == 2 || idx == 3 || idx == 5);
1505
7.38k
    if (opnds[idx - 1].reg.regno % 2 != 0)
1506
2.73k
      {
1507
2.73k
        set_syntax_error (mismatch_detail, idx - 1,
1508
2.73k
        _("reg pair must start from even reg"));
1509
2.73k
        return false;
1510
2.73k
      }
1511
4.65k
    if (opnds[idx].reg.regno != opnds[idx - 1].reg.regno + 1)
1512
0
      {
1513
0
        set_syntax_error (mismatch_detail, idx,
1514
0
        _("reg pair must be contiguous"));
1515
0
        return false;
1516
0
      }
1517
4.65k
    break;
1518
4.65k
  }
1519
1520
      /* <Xt> may be optional in some IC and TLBI instructions.  */
1521
5.36M
      if (type == AARCH64_OPND_Rt_SYS)
1522
950
  {
1523
950
    assert (idx == 1 && (aarch64_get_operand_class (opnds[0].type)
1524
950
             == AARCH64_OPND_CLASS_SYSTEM));
1525
950
    if (!(opnds[1].present && aarch64_sys_ins_reg_tlbid_xt (opnds[0].sysins_op)))
1526
939
      {
1527
939
        if (opnds[1].present
1528
931
      && !aarch64_sys_ins_reg_has_xt (opnds[0].sysins_op))
1529
623
    {
1530
623
      set_other_error (mismatch_detail, idx, _("extraneous register"));
1531
623
      return false;
1532
623
    }
1533
316
        if (!opnds[1].present
1534
8
      && 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
316
     }
1540
950
  }
1541
5.36M
      break;
1542
1543
5.36M
    case AARCH64_OPND_CLASS_SVE_REG:
1544
1.48M
      switch (type)
1545
1.48M
  {
1546
4.39k
  case AARCH64_OPND_SVE_Zm3_INDEX:
1547
12.2k
  case AARCH64_OPND_SVE_Zm3_22_INDEX:
1548
12.4k
  case AARCH64_OPND_SVE_Zm3_19_INDEX:
1549
18.5k
  case AARCH64_OPND_SVE_Zm3_11_INDEX:
1550
22.3k
  case AARCH64_OPND_SVE_Zm3_10_INDEX:
1551
25.7k
  case AARCH64_OPND_SVE_Zm4_11_INDEX:
1552
30.5k
  case AARCH64_OPND_SVE_Zm4_INDEX:
1553
30.5k
    size = get_operand_fields_width (get_operand_from_code (type));
1554
30.5k
    shift = get_operand_specific_data (&aarch64_operands[type]);
1555
30.5k
    if (!check_reglane (opnd, mismatch_detail, idx,
1556
30.5k
            "z", 0, (1 << shift) - 1,
1557
30.5k
            0, (1u << (size - shift)) - 1))
1558
0
      return false;
1559
30.5k
    break;
1560
1561
30.5k
  case AARCH64_OPND_SVE_Zm1_23_INDEX:
1562
427
    size = get_operand_fields_width (get_operand_from_code (type));
1563
427
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31, 0, 1))
1564
0
      return 0;
1565
427
    break;
1566
1567
427
  case AARCH64_OPND_SME_Zn_INDEX2_19:
1568
1.21k
  case AARCH64_OPND_SVE_Zm2_22_INDEX:
1569
1.21k
    size = get_operand_fields_width (get_operand_from_code (type));
1570
1.21k
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31, 0, 3))
1571
0
      return 0;
1572
1.21k
    break;
1573
1574
2.05k
  case AARCH64_OPND_SVE_Zn_INDEX:
1575
2.05k
    size = aarch64_get_qualifier_esize (opnd->qualifier);
1576
2.05k
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31,
1577
2.05k
            0, 64 / size - 1))
1578
0
      return false;
1579
2.05k
    break;
1580
1581
2.05k
  case AARCH64_OPND_SVE_Zn_5_INDEX:
1582
410
    size = aarch64_get_qualifier_esize (opnd->qualifier);
1583
410
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31,
1584
410
            0, 16 / size - 1))
1585
0
      return false;
1586
410
    break;
1587
1588
410
  case AARCH64_OPND_SME_PNn3_INDEX1:
1589
148
  case AARCH64_OPND_SME_PNn3_INDEX2:
1590
148
    size = get_operand_field_width (get_operand_from_code (type), 0);
1591
148
    if (!check_reglane (opnd, mismatch_detail, idx, "pn", 8, 15,
1592
148
            0, (1 << size) - 1))
1593
0
      return false;
1594
148
    break;
1595
1596
963
  case AARCH64_OPND_SVE_Zm3_12_INDEX:
1597
1.22k
  case AARCH64_OPND_SME_Zn_INDEX1_16:
1598
1.51k
  case AARCH64_OPND_SME_Zn_INDEX2_15:
1599
1.99k
  case AARCH64_OPND_SME_Zn_INDEX2_16:
1600
2.13k
  case AARCH64_OPND_SME_Zn_INDEX3_14:
1601
2.36k
  case AARCH64_OPND_SME_Zn_INDEX3_15:
1602
2.58k
  case AARCH64_OPND_SME_Zn_INDEX4_14:
1603
2.66k
  case AARCH64_OPND_SVE_Zn0_INDEX:
1604
2.75k
  case AARCH64_OPND_SVE_Zn1_17_INDEX:
1605
2.88k
  case AARCH64_OPND_SVE_Zn2_18_INDEX:
1606
2.97k
  case AARCH64_OPND_SVE_Zn3_22_INDEX:
1607
3.08k
  case AARCH64_OPND_SVE_Zd0_INDEX:
1608
3.18k
  case AARCH64_OPND_SVE_Zd1_17_INDEX:
1609
3.27k
  case AARCH64_OPND_SVE_Zd2_18_INDEX:
1610
3.30k
  case AARCH64_OPND_SVE_Zd3_22_INDEX:
1611
3.30k
    size = get_operand_fields_width (get_operand_from_code (type)) - 5;
1612
3.30k
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31,
1613
3.30k
            0, (1 << size) - 1))
1614
0
      return false;
1615
3.30k
    break;
1616
1617
3.30k
  case AARCH64_OPND_SME_Zm_INDEX1:
1618
2.85k
  case AARCH64_OPND_SME_Zm_INDEX2:
1619
2.96k
  case AARCH64_OPND_SME_Zm_INDEX2_3:
1620
4.76k
  case AARCH64_OPND_SME_Zm_INDEX3_1:
1621
6.94k
  case AARCH64_OPND_SME_Zm_INDEX3_2:
1622
7.72k
  case AARCH64_OPND_SME_Zm_INDEX3_3:
1623
12.0k
  case AARCH64_OPND_SME_Zm_INDEX3_10:
1624
14.1k
  case AARCH64_OPND_SME_Zm_INDEX4_1:
1625
14.9k
  case AARCH64_OPND_SME_Zm_INDEX4_2:
1626
30.5k
  case AARCH64_OPND_SME_Zm_INDEX4_3:
1627
35.9k
  case AARCH64_OPND_SME_Zm_INDEX4_10:
1628
35.9k
    size = get_operand_fields_width (get_operand_from_code (type)) - 5;
1629
35.9k
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 15,
1630
35.9k
            0, (1 << size) - 1))
1631
0
      return false;
1632
35.9k
    break;
1633
1634
35.9k
  case AARCH64_OPND_SME_Zk_INDEX:
1635
4.19k
    if (!check_reglane (opnd, mismatch_detail, idx, "z", 0, 31, 0, 3))
1636
0
      return false;
1637
4.19k
    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.19k
    break;
1644
1645
8.39k
  case AARCH64_OPND_SME_Zm:
1646
8.44k
  case AARCH64_OPND_SME_Zm_17:
1647
8.44k
    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.44k
    break;
1653
1654
8.44k
  case AARCH64_OPND_SME_Zn_6_3:
1655
8.36k
    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
8.36k
    break;
1662
1663
8.36k
  case AARCH64_OPND_SME_Zm_17_3:
1664
8.11k
    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
8.11k
    break;
1671
1672
8.11k
  case AARCH64_OPND_SME_PnT_Wm_imm:
1673
6.93k
    size = aarch64_get_qualifier_esize (opnd->qualifier);
1674
6.93k
    max_value = 16 / size - 1;
1675
6.93k
    if (!check_za_access (opnd, mismatch_detail, idx,
1676
6.93k
        12, max_value, 1, 0, get_opcode_dependent_value (opcode)))
1677
0
      return false;
1678
6.93k
    break;
1679
1680
1.37M
  default:
1681
1.37M
    break;
1682
1.48M
  }
1683
1.48M
      break;
1684
1685
1.48M
    case AARCH64_OPND_CLASS_SVE_REGLIST:
1686
325k
      switch (type)
1687
325k
  {
1688
772
  case AARCH64_OPND_SME_Pdx2:
1689
21.7k
  case AARCH64_OPND_SME_Zdnx2:
1690
28.3k
  case AARCH64_OPND_SME_Zdnx4:
1691
28.7k
  case AARCH64_OPND_SME_Znx2_6_3:
1692
29.4k
  case AARCH64_OPND_SME_Zmx2_17_3:
1693
31.8k
  case AARCH64_OPND_SME_Zmx2:
1694
32.2k
  case AARCH64_OPND_SME_Zmx4:
1695
48.5k
  case AARCH64_OPND_SME_Znx2:
1696
48.5k
  case AARCH64_OPND_SME_Znx2_BIT_INDEX:
1697
53.3k
  case AARCH64_OPND_SME_Znx4:
1698
53.3k
    num = get_operand_specific_data (&aarch64_operands[type]);
1699
53.3k
    if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
1700
0
      return false;
1701
53.3k
    if (((opnd->reglist.first_regno % num) != 0)
1702
53.3k
        || (type == AARCH64_OPND_SME_Znx2_6_3
1703
432
      && opnd->reglist.first_regno > 15)
1704
53.3k
        || (type == AARCH64_OPND_SME_Zmx2_17_3
1705
677
      && 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
53.3k
    break;
1712
1713
53.3k
  case AARCH64_OPND_SME_Ztx2_STRIDED:
1714
11.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
11.0k
    num = get_operand_specific_data (&aarch64_operands[type]);
1718
11.0k
    if (!check_reglist (opnd, mismatch_detail, idx, num, 16 / num))
1719
0
      return false;
1720
11.0k
    num = 16 | (opnd->reglist.stride - 1);
1721
11.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
11.0k
    break;
1728
1729
11.0k
  case AARCH64_OPND_SME_PdxN:
1730
12.1k
  case AARCH64_OPND_SVE_ZnxN:
1731
260k
  case AARCH64_OPND_SVE_ZtxN:
1732
260k
    num = get_opcode_dependent_value (opcode);
1733
260k
    if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
1734
0
      return false;
1735
260k
    break;
1736
1737
260k
  case AARCH64_OPND_SME_Zmx2_INDEX_22:
1738
169
    num = get_operand_specific_data (&aarch64_operands[type]);
1739
169
    if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
1740
0
        return false;
1741
169
    break;
1742
1743
169
  case AARCH64_OPND_SME_Zn7xN_UNTYPED:
1744
85
    num = get_opcode_dependent_value (opcode);
1745
85
    if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
1746
0
        return false;
1747
85
    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
85
    break;
1753
1754
85
  default:
1755
0
    abort ();
1756
325k
  }
1757
325k
      break;
1758
1759
325k
    case AARCH64_OPND_CLASS_ZA_ACCESS:
1760
170k
      switch (type)
1761
170k
  {
1762
1.04k
  case AARCH64_OPND_SME_ZA_HV_idx_src:
1763
70.1k
  case AARCH64_OPND_SME_ZA_HV_idx_dest:
1764
113k
  case AARCH64_OPND_SME_ZA_HV_idx_ldstr:
1765
113k
    size = aarch64_get_qualifier_esize (opnd->qualifier);
1766
113k
    max_value = 16 / size - 1;
1767
113k
    if (!check_za_access (opnd, mismatch_detail, idx, 12, max_value, 1,
1768
113k
        get_opcode_dependent_value (opcode),
1769
113k
        get_opcode_dependent_vg_status (opcode)))
1770
0
      return false;
1771
113k
    break;
1772
1773
113k
  case AARCH64_OPND_SME_ZA_array_off4:
1774
951
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 15, 1,
1775
951
        get_opcode_dependent_value (opcode),
1776
951
        get_opcode_dependent_vg_status (opcode)))
1777
0
      return false;
1778
951
    break;
1779
1780
9.74k
  case AARCH64_OPND_SME_ZA_array_off3_0:
1781
10.5k
  case AARCH64_OPND_SME_ZA_array_off3_5:
1782
10.5k
    if (!check_za_access (opnd, mismatch_detail, idx, 8, 7, 1,
1783
10.5k
        get_opcode_dependent_value (opcode),
1784
10.5k
        get_opcode_dependent_vg_status (opcode)))
1785
0
      return false;
1786
10.5k
    break;
1787
1788
10.5k
  case AARCH64_OPND_SME_ZA_array_off1x4:
1789
6.02k
    if (!check_za_access (opnd, mismatch_detail, idx, 8, 1, 4,
1790
6.02k
        get_opcode_dependent_value (opcode),
1791
6.02k
        get_opcode_dependent_vg_status (opcode)))
1792
0
      return false;
1793
6.02k
    break;
1794
1795
6.02k
  case AARCH64_OPND_SME_ZA_array_off2x2:
1796
4.95k
    if (!check_za_access (opnd, mismatch_detail, idx, 8, 3, 2,
1797
4.95k
        get_opcode_dependent_value (opcode),
1798
4.95k
        get_opcode_dependent_vg_status (opcode)))
1799
0
      return false;
1800
4.95k
    break;
1801
1802
6.39k
  case AARCH64_OPND_SME_ZA_array_off2x4:
1803
6.39k
    if (!check_za_access (opnd, mismatch_detail, idx, 8, 3, 4,
1804
6.39k
        get_opcode_dependent_value (opcode),
1805
6.39k
        get_opcode_dependent_vg_status (opcode)))
1806
0
      return false;
1807
6.39k
    break;
1808
1809
20.1k
  case AARCH64_OPND_SME_ZA_array_off3x2:
1810
20.1k
    if (!check_za_access (opnd, mismatch_detail, idx, 8, 7, 2,
1811
20.1k
        get_opcode_dependent_value (opcode),
1812
20.1k
        get_opcode_dependent_vg_status (opcode)))
1813
0
      return false;
1814
20.1k
    break;
1815
1816
20.1k
  case AARCH64_OPND_SME_ZA_array_vrsb_1:
1817
198
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 7, 2,
1818
198
        get_opcode_dependent_value (opcode),
1819
198
        get_opcode_dependent_vg_status (opcode)))
1820
0
      return false;
1821
198
    break;
1822
1823
198
  case AARCH64_OPND_SME_ZA_array_vrsh_1:
1824
50
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 3, 2,
1825
50
        get_opcode_dependent_value (opcode),
1826
50
        get_opcode_dependent_vg_status (opcode)))
1827
0
      return false;
1828
50
    break;
1829
1830
50
  case AARCH64_OPND_SME_ZA_array_vrss_1:
1831
31
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 1, 2,
1832
31
        get_opcode_dependent_value (opcode),
1833
31
        get_opcode_dependent_vg_status (opcode)))
1834
0
      return false;
1835
31
    break;
1836
1837
265
  case AARCH64_OPND_SME_ZA_array_vrsd_1:
1838
265
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 0, 2,
1839
265
        get_opcode_dependent_value (opcode),
1840
265
        get_opcode_dependent_vg_status (opcode)))
1841
0
      return false;
1842
265
    break;
1843
1844
265
  case AARCH64_OPND_SME_ZA_array_vrsb_2:
1845
200
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 3, 4,
1846
200
        get_opcode_dependent_value (opcode),
1847
200
        get_opcode_dependent_vg_status (opcode)))
1848
0
      return false;
1849
200
    break;
1850
1851
200
  case AARCH64_OPND_SME_ZA_array_vrsh_2:
1852
61
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 1, 4,
1853
61
        get_opcode_dependent_value (opcode),
1854
61
        get_opcode_dependent_vg_status (opcode)))
1855
0
      return false;
1856
61
    break;
1857
1858
770
  case AARCH64_OPND_SME_ZA_ARRAY4:
1859
770
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 15, 1,
1860
770
        get_opcode_dependent_value (opcode),
1861
770
        get_opcode_dependent_vg_status (opcode)))
1862
0
      return false;
1863
770
    break;
1864
1865
770
  case AARCH64_OPND_SME_ZA_array_vrss_2:
1866
441
  case AARCH64_OPND_SME_ZA_array_vrsd_2:
1867
441
    if (!check_za_access (opnd, mismatch_detail, idx, 12, 0, 4,
1868
441
        get_opcode_dependent_value (opcode),
1869
441
        get_opcode_dependent_vg_status (opcode)))
1870
0
      return false;
1871
441
    break;
1872
1873
4.25k
  case AARCH64_OPND_SME_ZA_HV_idx_srcxN:
1874
6.09k
  case AARCH64_OPND_SME_ZA_HV_idx_destxN:
1875
6.09k
    size = aarch64_get_qualifier_esize (opnd->qualifier);
1876
6.09k
    num = get_opcode_dependent_value (opcode);
1877
6.09k
    max_value = 16 / num / size;
1878
6.09k
    if (max_value > 0)
1879
5.94k
      max_value -= 1;
1880
6.09k
    if (!check_za_access (opnd, mismatch_detail, idx, 12, max_value, num,
1881
6.09k
        0, get_opcode_dependent_value (opcode)))
1882
0
      return false;
1883
6.09k
    break;
1884
1885
6.09k
  default:
1886
0
    abort ();
1887
170k
  }
1888
170k
      break;
1889
1890
917k
    case AARCH64_OPND_CLASS_PRED_REG:
1891
917k
      switch (type)
1892
917k
  {
1893
1.58k
  case AARCH64_OPND_SME_PNd3:
1894
29.4k
  case AARCH64_OPND_SME_PNg3:
1895
29.4k
    if (opnd->reg.regno < 8)
1896
0
      {
1897
0
        set_invalid_regno_error (mismatch_detail, idx, "pn", 8, 15);
1898
0
        return false;
1899
0
      }
1900
29.4k
    break;
1901
1902
888k
  default:
1903
888k
    if (opnd->reg.regno >= 8
1904
62.6k
        && 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
888k
    break;
1910
917k
  }
1911
917k
      break;
1912
1913
917k
    case AARCH64_OPND_CLASS_COND:
1914
22.3k
      if (type == AARCH64_OPND_COND1
1915
406
    && (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
22.3k
      break;
1921
1922
2.87M
    case AARCH64_OPND_CLASS_ADDRESS:
1923
      /* Check writeback.  */
1924
2.87M
      switch (opcode->iclass)
1925
2.87M
  {
1926
216k
  case ldst_pos:
1927
289k
  case ldst_unscaled:
1928
419k
  case ldstnapair_offs:
1929
584k
  case ldstpair_off:
1930
596k
  case ldst_unpriv:
1931
596k
    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
596k
    break;
1938
596k
  case ldst_imm10:
1939
9.90k
    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
9.90k
    break;
1946
47.3k
  case ldst_imm9:
1947
270k
  case ldstpair_indexed:
1948
276k
  case asisdlsep:
1949
288k
  case asisdlsop:
1950
288k
    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
288k
    break;
1957
288k
  case rcpc3:
1958
22.6k
    if (opnd->addr.writeback)
1959
1.67k
      if ((type == AARCH64_OPND_RCPC3_ADDR_PREIND_WB
1960
272
     && !opnd->addr.preind)
1961
1.67k
    || (type == AARCH64_OPND_RCPC3_ADDR_POSTIND
1962
58
        && !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
22.6k
    break;
1970
1.95M
  default:
1971
1.95M
    assert (opnd->addr.writeback == 0);
1972
1.95M
    break;
1973
2.87M
  }
1974
2.87M
      switch (type)
1975
2.87M
  {
1976
497k
  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
497k
    size = aarch64_get_qualifier_esize (opnd->qualifier);
1982
497k
    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
497k
    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
497k
    break;
1994
497k
  case AARCH64_OPND_ADDR_OFFSET:
1995
125k
  case AARCH64_OPND_ADDR_SIMM9:
1996
    /* Unscaled signed 9 bits immediate offset.  */
1997
125k
    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
125k
    break;
2003
2004
125k
  case AARCH64_OPND_ADDR_SIMM10:
2005
    /* Scaled signed 10 bits immediate offset.  */
2006
9.90k
    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
9.90k
    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
9.90k
    break;
2017
2018
21.5k
  case AARCH64_OPND_ADDR_SIMM11:
2019
    /* Signed 11 bits immediate offset (multiple of 16).  */
2020
21.5k
    if (!value_in_range_p (opnd->addr.offset.imm, -1024, 1008))
2021
0
      {
2022
0
        set_offset_out_of_range_error (mismatch_detail, idx, -1024, 1008);
2023
0
        return false;
2024
0
      }
2025
2026
21.5k
    if (!value_aligned_p (opnd->addr.offset.imm, 16))
2027
0
      {
2028
0
        set_unaligned_error (mismatch_detail, idx, 16);
2029
0
        return false;
2030
0
      }
2031
21.5k
    break;
2032
2033
21.5k
  case AARCH64_OPND_ADDR_SIMM13:
2034
    /* Signed 13 bits immediate offset (multiple of 16).  */
2035
7.13k
    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.13k
    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.13k
    break;
2047
2048
17.7k
  case AARCH64_OPND_SIMD_ADDR_POST:
2049
    /* AdvSIMD load/store multiple structures, post-index.  */
2050
17.7k
    assert (idx == 1);
2051
17.7k
    if (opnd->addr.offset.is_reg)
2052
15.0k
      {
2053
15.0k
        if (value_in_range_p (opnd->addr.offset.regno, 0, 30))
2054
15.0k
    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
15.0k
      }
2062
2.73k
    else
2063
2.73k
      {
2064
2.73k
        const aarch64_opnd_info *prev = &opnds[idx-1];
2065
2.73k
        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
2.73k
        int is_ld1r = get_opcode_dependent_value (opcode) == 1;
2069
2.73k
        if (opcode->operands[0] == AARCH64_OPND_LVt_AL)
2070
    /* Special handling of loading single structure to all lane.  */
2071
493
    num_bytes = (is_ld1r ? 1 : prev->reglist.num_regs)
2072
493
      * aarch64_get_qualifier_esize (prev->qualifier);
2073
2.24k
        else
2074
2.24k
    num_bytes = prev->reglist.num_regs
2075
2.24k
      * aarch64_get_qualifier_esize (prev->qualifier)
2076
2.24k
      * aarch64_get_qualifier_nelem (prev->qualifier);
2077
2.73k
        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
2.73k
      }
2084
2.73k
    break;
2085
2086
62.8k
  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
62.8k
    size = aarch64_get_qualifier_esize (opnd->qualifier);
2091
    /* It is either no shift or shift by the binary logarithm of SIZE.  */
2092
62.8k
    if (opnd->shifter.amount != 0
2093
37.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
62.8k
    switch (opnd->shifter.kind)
2102
62.8k
      {
2103
1.81k
      case AARCH64_MOD_UXTW:
2104
19.4k
      case AARCH64_MOD_LSL:
2105
21.7k
      case AARCH64_MOD_SXTW:
2106
26.5k
      case AARCH64_MOD_SXTX: break;
2107
36.2k
      default:
2108
36.2k
        set_other_error (mismatch_detail, idx,
2109
36.2k
             _("invalid extend/shift operator"));
2110
36.2k
        return false;
2111
62.8k
      }
2112
26.5k
    break;
2113
2114
216k
  case AARCH64_OPND_ADDR_UIMM12:
2115
216k
    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
216k
    size = aarch64_get_qualifier_esize (qualifier);
2120
216k
    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
216k
    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
216k
    break;
2132
2133
216k
  case AARCH64_OPND_ADDR_PCREL9:
2134
257k
  case AARCH64_OPND_ADDR_PCREL14:
2135
653k
  case AARCH64_OPND_ADDR_PCREL19:
2136
954k
  case AARCH64_OPND_ADDR_PCREL21:
2137
1.17M
  case AARCH64_OPND_ADDR_PCREL26:
2138
1.17M
    {
2139
1.17M
      imm = opnd->imm.value;
2140
1.17M
      if (operand_need_shift_by_two (get_operand_from_code (type)))
2141
872k
        {
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
872k
    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
872k
    imm >>= 2;
2152
872k
        }
2153
2154
1.17M
      if (!check_immediate_out_of_range (imm, type, mismatch_detail, idx))
2155
0
        return false;
2156
1.17M
    }
2157
1.17M
    break;
2158
2159
1.17M
  case AARCH64_OPND_SME_ADDR_RI_U4xVL:
2160
951
    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
951
    break;
2166
2167
61.7k
  case AARCH64_OPND_SVE_ADDR_RI_S4xVL:
2168
73.0k
  case AARCH64_OPND_SVE_ADDR_RI_S4x2xVL:
2169
76.7k
  case AARCH64_OPND_SVE_ADDR_RI_S4x3xVL:
2170
83.8k
  case AARCH64_OPND_SVE_ADDR_RI_S4x4xVL:
2171
83.8k
    min_value = -8;
2172
83.8k
    max_value = 7;
2173
91.5k
  sve_imm_offset_vl:
2174
91.5k
    assert (!opnd->addr.offset.is_reg);
2175
91.5k
    assert (opnd->addr.preind);
2176
91.5k
    num = 1 + get_operand_specific_data (&aarch64_operands[type]);
2177
91.5k
    min_value *= num;
2178
91.5k
    max_value *= num;
2179
91.5k
    if ((opnd->addr.offset.imm != 0 && !opnd->shifter.operator_present)
2180
91.5k
        || (opnd->shifter.operator_present
2181
85.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
91.5k
    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
91.5k
    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
91.5k
    break;
2199
2200
91.5k
  case AARCH64_OPND_SVE_ADDR_RI_S6xVL:
2201
2.71k
    min_value = -32;
2202
2.71k
    max_value = 31;
2203
2.71k
    goto sve_imm_offset_vl;
2204
2205
5.06k
  case AARCH64_OPND_SVE_ADDR_RI_S9xVL:
2206
5.06k
    min_value = -256;
2207
5.06k
    max_value = 255;
2208
5.06k
    goto sve_imm_offset_vl;
2209
2210
5.01k
  case AARCH64_OPND_SVE_ADDR_RI_U6:
2211
9.47k
  case AARCH64_OPND_SVE_ADDR_RI_U6x2:
2212
11.0k
  case AARCH64_OPND_SVE_ADDR_RI_U6x4:
2213
12.4k
  case AARCH64_OPND_SVE_ADDR_RI_U6x8:
2214
12.4k
    min_value = 0;
2215
12.4k
    max_value = 63;
2216
30.0k
  sve_imm_offset:
2217
30.0k
    assert (!opnd->addr.offset.is_reg);
2218
30.0k
    assert (opnd->addr.preind);
2219
30.0k
    num = 1 << get_operand_specific_data (&aarch64_operands[type]);
2220
30.0k
    min_value *= num;
2221
30.0k
    max_value *= num;
2222
30.0k
    if (opnd->shifter.operator_present
2223
30.0k
        || 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
30.0k
    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
30.0k
    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
30.0k
    break;
2241
2242
30.0k
  case AARCH64_OPND_SVE_ADDR_RI_S4x16:
2243
3.30k
  case AARCH64_OPND_SVE_ADDR_RI_S4x32:
2244
3.30k
    min_value = -8;
2245
3.30k
    max_value = 7;
2246
3.30k
    goto sve_imm_offset;
2247
2248
12.6k
  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
12.6k
    assert (opnd->addr.offset.is_reg);
2253
12.6k
    assert (opnd->addr.preind);
2254
12.6k
    assert ((aarch64_operands[type].flags & OPD_F_NO_ZR) == 0);
2255
12.6k
    assert (opnd->shifter.kind == AARCH64_MOD_LSL);
2256
12.6k
    assert (opnd->shifter.operator_present == 0);
2257
12.6k
    break;
2258
2259
12.6k
  case AARCH64_OPND_SVE_ADDR_RR:
2260
18.3k
  case AARCH64_OPND_SVE_ADDR_RR_LSL1:
2261
22.2k
  case AARCH64_OPND_SVE_ADDR_RR_LSL2:
2262
38.4k
  case AARCH64_OPND_SVE_ADDR_RR_LSL3:
2263
53.5k
  case AARCH64_OPND_SVE_ADDR_RR_LSL4:
2264
61.2k
  case AARCH64_OPND_SVE_ADDR_RM:
2265
65.0k
  case AARCH64_OPND_SVE_ADDR_RM_LSL1:
2266
69.3k
  case AARCH64_OPND_SVE_ADDR_RM_LSL2:
2267
72.8k
  case AARCH64_OPND_SVE_ADDR_RM_LSL3:
2268
72.8k
  case AARCH64_OPND_SVE_ADDR_RM_LSL4:
2269
87.9k
  case AARCH64_OPND_SVE_ADDR_RX:
2270
97.0k
  case AARCH64_OPND_SVE_ADDR_RX_LSL1:
2271
106k
  case AARCH64_OPND_SVE_ADDR_RX_LSL2:
2272
112k
  case AARCH64_OPND_SVE_ADDR_RX_LSL3:
2273
116k
  case AARCH64_OPND_SVE_ADDR_RX_LSL4:
2274
135k
  case AARCH64_OPND_SVE_ADDR_RZ:
2275
138k
  case AARCH64_OPND_SVE_ADDR_RZ_LSL1:
2276
141k
  case AARCH64_OPND_SVE_ADDR_RZ_LSL2:
2277
143k
  case AARCH64_OPND_SVE_ADDR_RZ_LSL3:
2278
143k
    modifiers = 1 << AARCH64_MOD_LSL;
2279
208k
  sve_rr_operand:
2280
208k
    assert (opnd->addr.offset.is_reg);
2281
208k
    assert (opnd->addr.preind);
2282
208k
    if ((aarch64_operands[type].flags & OPD_F_NO_ZR) != 0
2283
43.2k
        && 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
208k
    if (((1 << opnd->shifter.kind) & modifiers) == 0
2290
208k
        || (opnd->shifter.amount
2291
208k
      != 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
208k
    break;
2298
2299
208k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW_14:
2300
41.0k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW_22:
2301
42.5k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW1_14:
2302
50.3k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW1_22:
2303
51.3k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW2_14:
2304
57.3k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW2_22:
2305
58.0k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW3_14:
2306
64.7k
  case AARCH64_OPND_SVE_ADDR_RZ_XTW3_22:
2307
64.7k
    modifiers = (1 << AARCH64_MOD_SXTW) | (1 << AARCH64_MOD_UXTW);
2308
64.7k
    goto sve_rr_operand;
2309
2310
4.74k
  case AARCH64_OPND_SVE_ADDR_ZI_U5:
2311
10.6k
  case AARCH64_OPND_SVE_ADDR_ZI_U5x2:
2312
13.1k
  case AARCH64_OPND_SVE_ADDR_ZI_U5x4:
2313
14.3k
  case AARCH64_OPND_SVE_ADDR_ZI_U5x8:
2314
14.3k
    min_value = 0;
2315
14.3k
    max_value = 31;
2316
14.3k
    goto sve_imm_offset;
2317
2318
920
  case AARCH64_OPND_SVE_ADDR_ZZ_LSL:
2319
920
    modifiers = 1 << AARCH64_MOD_LSL;
2320
2.07k
  sve_zz_operand:
2321
2.07k
    assert (opnd->addr.offset.is_reg);
2322
2.07k
    assert (opnd->addr.preind);
2323
2.07k
    if (((1 << opnd->shifter.kind) & modifiers) == 0
2324
2.07k
        || opnd->shifter.amount < 0
2325
2.07k
        || 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.07k
    break;
2332
2333
2.07k
  case AARCH64_OPND_SVE_ADDR_ZZ_SXTW:
2334
289
    modifiers = (1 << AARCH64_MOD_SXTW);
2335
289
    goto sve_zz_operand;
2336
2337
862
  case AARCH64_OPND_SVE_ADDR_ZZ_UXTW:
2338
862
    modifiers = 1 << AARCH64_MOD_UXTW;
2339
862
    goto sve_zz_operand;
2340
2341
14.9k
  case AARCH64_OPND_RCPC3_ADDR_OPT_PREIND_WB:
2342
15.8k
  case AARCH64_OPND_RCPC3_ADDR_OPT_POSTIND:
2343
16.1k
  case AARCH64_OPND_RCPC3_ADDR_PREIND_WB:
2344
16.1k
  case AARCH64_OPND_RCPC3_ADDR_POSTIND:
2345
16.1k
    {
2346
16.1k
      int num_bytes = calc_ldst_datasize (opnds);
2347
16.1k
      int abs_offset = (type == AARCH64_OPND_RCPC3_ADDR_OPT_PREIND_WB
2348
1.23k
            || type == AARCH64_OPND_RCPC3_ADDR_PREIND_WB)
2349
16.1k
        ? opnd->addr.offset.imm * -1
2350
16.1k
        : opnd->addr.offset.imm;
2351
16.1k
      if ((int) num_bytes != abs_offset
2352
14.5k
    && opnd->addr.offset.imm != 0)
2353
0
        {
2354
0
    set_other_error (mismatch_detail, idx,
2355
0
         _("invalid increment amount"));
2356
0
    return false;
2357
0
        }
2358
16.1k
    }
2359
16.1k
    break;
2360
2361
16.1k
  case AARCH64_OPND_RCPC3_ADDR_OFFSET:
2362
6.43k
    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
379k
  default:
2369
379k
    break;
2370
2.87M
  }
2371
2.82M
      break;
2372
2373
2.82M
    case AARCH64_OPND_CLASS_SIMD_REGLIST:
2374
51.5k
      if (type == AARCH64_OPND_LEt)
2375
18.1k
  {
2376
    /* Get the upper bound for the element index.  */
2377
18.1k
    num = 16 / aarch64_get_qualifier_esize (qualifier) - 1;
2378
18.1k
    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
18.1k
  }
2384
      /* The opcode dependent area stores the number of elements in
2385
   each structure to be loaded/stored.  */
2386
51.5k
      num = get_opcode_dependent_value (opcode);
2387
51.5k
      switch (type)
2388
51.5k
  {
2389
3.49k
  case AARCH64_OPND_LVn_LUT:
2390
3.49k
    if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
2391
0
      return 0;
2392
3.49k
    break;
2393
12.5k
  case AARCH64_OPND_LVt:
2394
12.5k
    assert (num >= 1 && num <= 4);
2395
    /* Unless LD1/ST1, the number of registers should be equal to that
2396
       of the structure elements.  */
2397
12.5k
    if (num != 1 && !check_reglist (opnd, mismatch_detail, idx, num, 1))
2398
676
      return false;
2399
11.8k
    break;
2400
11.8k
  case AARCH64_OPND_LVt_AL:
2401
19.9k
  case AARCH64_OPND_LEt:
2402
19.9k
    assert (num >= 1 && num <= 4);
2403
    /* The number of registers should be equal to that of the structure
2404
       elements.  */
2405
19.9k
    if (!check_reglist (opnd, mismatch_detail, idx, num, 1))
2406
0
      return false;
2407
19.9k
    break;
2408
19.9k
  default:
2409
15.5k
    break;
2410
51.5k
  }
2411
50.8k
      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
50.8k
      break;
2417
2418
3.05M
    case AARCH64_OPND_CLASS_IMMEDIATE:
2419
      /* Constraint check on immediate operand.  */
2420
3.05M
      imm = opnd->imm.value;
2421
      /* E.g. imm_0_31 constrains value to be 0..31.  */
2422
3.05M
      if (qualifier_value_in_range_constraint_p (qualifier)
2423
383k
    && !value_in_range_p (imm, get_lower_bound (qualifier),
2424
383k
        get_upper_bound (qualifier)))
2425
41.3k
  {
2426
41.3k
    set_imm_out_of_range_error (mismatch_detail, idx,
2427
41.3k
              get_lower_bound (qualifier),
2428
41.3k
              get_upper_bound (qualifier));
2429
41.3k
    return false;
2430
41.3k
  }
2431
2432
3.01M
      switch (type)
2433
3.01M
  {
2434
394k
  case AARCH64_OPND_AIMM:
2435
394k
    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
394k
    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
394k
    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
394k
    break;
2454
2455
394k
  case AARCH64_OPND_HALF:
2456
96.0k
    assert (idx == 1 && opnds[0].type == AARCH64_OPND_Rd);
2457
96.0k
    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
96.0k
    size = aarch64_get_qualifier_esize (opnds[0].qualifier);
2464
96.0k
    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
96.0k
    if (!value_in_range_p (opnd->shifter.amount, 0, size * 8 - 16))
2471
16.3k
      {
2472
16.3k
        set_sft_amount_out_of_range_error (mismatch_detail, idx,
2473
16.3k
             0, size * 8 - 16);
2474
16.3k
        return false;
2475
16.3k
      }
2476
79.7k
    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
79.7k
    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
79.7k
    break;
2489
2490
79.7k
  case AARCH64_OPND_IMM_MOV:
2491
55.1k
      {
2492
55.1k
        int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
2493
55.1k
        imm = opnd->imm.value;
2494
55.1k
        assert (idx == 1);
2495
55.1k
        switch (opcode->op)
2496
55.1k
    {
2497
29.1k
    case OP_MOV_IMM_WIDEN:
2498
29.1k
      imm = ~imm;
2499
      /* Fall through.  */
2500
54.4k
    case OP_MOV_IMM_WIDE:
2501
54.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
54.4k
      break;
2508
54.4k
    case OP_MOV_IMM_LOG:
2509
753
      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
753
      break;
2516
753
    default:
2517
0
      assert (0);
2518
0
      return false;
2519
55.1k
    }
2520
55.1k
      }
2521
55.1k
    break;
2522
2523
55.1k
  case AARCH64_OPND_NZCV:
2524
11.0k
  case AARCH64_OPND_CCMP_IMM:
2525
11.9k
  case AARCH64_OPND_EXCEPTION:
2526
1.64M
  case AARCH64_OPND_UNDEFINED:
2527
1.64M
  case AARCH64_OPND_TME_UIMM16:
2528
1.64M
  case AARCH64_OPND_UIMM4:
2529
1.64M
  case AARCH64_OPND_UIMM4_ADDG:
2530
1.64M
  case AARCH64_OPND_UIMM7:
2531
1.65M
  case AARCH64_OPND_UIMM3_OP1:
2532
1.66M
  case AARCH64_OPND_UIMM3_OP2:
2533
1.66M
  case AARCH64_OPND_SVE_UIMM3:
2534
1.68M
  case AARCH64_OPND_SVE_UIMM7:
2535
1.68M
  case AARCH64_OPND_SVE_UIMM8:
2536
1.68M
  case AARCH64_OPND_SVE_UIMM4:
2537
1.69M
  case AARCH64_OPND_SVE_UIMM8_53:
2538
1.69M
  case AARCH64_OPND_CSSC_UIMM8:
2539
1.69M
    size = get_operand_fields_width (get_operand_from_code (type));
2540
1.69M
    assert (size < 32);
2541
1.69M
    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.69M
    break;
2548
2549
1.69M
  case AARCH64_OPND_UIMM10:
2550
    /* Scaled unsigned 10 bits immediate offset.  */
2551
3.05k
    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
3.05k
    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
3.05k
    break;
2563
2564
11.2k
  case AARCH64_OPND_SIMM5:
2565
11.7k
  case AARCH64_OPND_SVE_SIMM5:
2566
12.0k
  case AARCH64_OPND_SVE_SIMM5B:
2567
12.7k
  case AARCH64_OPND_SVE_SIMM6:
2568
13.5k
  case AARCH64_OPND_SVE_SIMM8:
2569
15.4k
  case AARCH64_OPND_CSSC_SIMM8:
2570
15.4k
    size = get_operand_fields_width (get_operand_from_code (type));
2571
15.4k
    assert (size < 32);
2572
15.4k
    if (!value_fit_signed_field_p (opnd->imm.value, size))
2573
0
      {
2574
0
        imm_range_t rng = imm_range_min_max (size, true);
2575
0
        set_imm_out_of_range_error (mismatch_detail, idx, rng.min,
2576
0
            rng.max);
2577
0
        return false;
2578
0
      }
2579
15.4k
    break;
2580
2581
28.1k
  case AARCH64_OPND_WIDTH:
2582
28.1k
    assert (idx > 1 && opnds[idx-1].type == AARCH64_OPND_IMM
2583
28.1k
      && opnds[0].type == AARCH64_OPND_Rd);
2584
28.1k
    size = get_upper_bound (qualifier);
2585
28.1k
    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
28.1k
    break;
2593
2594
270k
  case AARCH64_OPND_LIMM:
2595
305k
  case AARCH64_OPND_SVE_LIMM:
2596
305k
    {
2597
305k
      int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
2598
305k
      uint64_t uimm = opnd->imm.value;
2599
305k
      if (opcode->op == OP_BIC)
2600
0
        uimm = ~uimm;
2601
305k
      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
305k
    }
2608
305k
    break;
2609
2610
305k
  case AARCH64_OPND_IMM0:
2611
606
  case AARCH64_OPND_FPIMM0:
2612
606
    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
606
    break;
2619
2620
771
  case AARCH64_OPND_IMM_ROT1:
2621
15.2k
  case AARCH64_OPND_IMM_ROT2:
2622
23.3k
  case AARCH64_OPND_SVE_IMM_ROT2:
2623
23.3k
    if (opnd->imm.value != 0
2624
17.0k
        && opnd->imm.value != 90
2625
11.1k
        && opnd->imm.value != 180
2626
6.91k
        && 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
23.3k
    break;
2633
2634
23.3k
  case AARCH64_OPND_IMM_ROT3:
2635
1.07k
  case AARCH64_OPND_SVE_IMM_ROT1:
2636
1.41k
  case AARCH64_OPND_SVE_IMM_ROT3:
2637
1.41k
    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.41k
    break;
2644
2645
1.41k
  case AARCH64_OPND_SHLL_IMM:
2646
132
    assert (idx == 2);
2647
132
    size = 8 * aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
2648
132
    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
132
    break;
2655
2656
7.80k
  case AARCH64_OPND_IMM_VLSL:
2657
7.80k
    size = aarch64_get_qualifier_esize (qualifier);
2658
7.80k
    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
7.80k
    break;
2665
2666
12.7k
  case AARCH64_OPND_IMM_VLSR:
2667
12.7k
    size = aarch64_get_qualifier_esize (qualifier);
2668
12.7k
    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
12.7k
    break;
2674
2675
12.7k
  case AARCH64_OPND_SIMD_IMM:
2676
4.05k
  case AARCH64_OPND_SIMD_IMM_SFT:
2677
    /* Qualifier check.  */
2678
4.05k
    switch (qualifier)
2679
4.05k
      {
2680
2.78k
      case AARCH64_OPND_QLF_LSL:
2681
2.78k
        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
2.78k
        break;
2688
2.78k
      case AARCH64_OPND_QLF_MSL:
2689
417
        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
417
        break;
2696
853
      case AARCH64_OPND_QLF_NIL:
2697
853
        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
853
        break;
2704
853
      default:
2705
0
        assert (0);
2706
0
        return false;
2707
4.05k
      }
2708
    /* Is the immediate valid?  */
2709
4.05k
    assert (idx == 1);
2710
4.05k
    if (aarch64_get_qualifier_esize (opnds[0].qualifier) != 8)
2711
3.19k
      {
2712
        /* uimm8 or simm8 */
2713
3.19k
        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.19k
      }
2719
853
    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.05k
    switch (opnd->shifter.kind)
2730
4.05k
      {
2731
2.78k
      case AARCH64_MOD_LSL:
2732
2.78k
        size = aarch64_get_qualifier_esize (opnds[0].qualifier);
2733
2.78k
        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
2.78k
        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
2.78k
        break;
2745
2.78k
      case AARCH64_MOD_MSL:
2746
        /* Only 8 and 16 are valid shift amount.  */
2747
417
        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
417
        break;
2754
853
      default:
2755
853
        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
853
        break;
2762
4.05k
      }
2763
4.05k
    break;
2764
2765
4.05k
  case AARCH64_OPND_FPIMM:
2766
2.36k
  case AARCH64_OPND_SIMD_FPIMM:
2767
3.78k
  case AARCH64_OPND_SVE_FPIMM8:
2768
3.78k
    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.78k
    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.78k
    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.78k
    break;
2791
2792
3.78k
  case AARCH64_OPND_SVE_AIMM:
2793
2.54k
    min_value = 0;
2794
16.7k
  sve_aimm:
2795
16.7k
    assert (opnd->shifter.kind == AARCH64_MOD_LSL);
2796
16.7k
    size = aarch64_get_qualifier_esize (opnds[0].qualifier);
2797
16.7k
    mask = ~((uint64_t) -1 << (size * 4) << (size * 4));
2798
16.7k
    uvalue = opnd->imm.value;
2799
16.7k
    shift = opnd->shifter.amount;
2800
16.7k
    if (size == 1)
2801
3.88k
      {
2802
3.88k
        if (shift != 0)
2803
113
    {
2804
113
      set_other_error (mismatch_detail, idx,
2805
113
           _("no shift amount allowed for"
2806
113
             " 8-bit constants"));
2807
113
      return false;
2808
113
    }
2809
3.88k
      }
2810
12.8k
    else
2811
12.8k
      {
2812
12.8k
        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
12.8k
        if (shift == 0 && (uvalue & 0xff) == 0)
2819
4.53k
    {
2820
4.53k
      shift = 8;
2821
4.53k
      uvalue = (int64_t) uvalue / 256;
2822
4.53k
    }
2823
12.8k
      }
2824
16.6k
    mask >>= shift;
2825
16.6k
    if ((uvalue & mask) != uvalue && (uvalue | ~mask) != uvalue)
2826
1.43k
      {
2827
1.43k
        set_other_error (mismatch_detail, idx,
2828
1.43k
             _("immediate too big for element size"));
2829
1.43k
        return false;
2830
1.43k
      }
2831
15.1k
    uvalue = (uvalue - min_value) & mask;
2832
15.1k
    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
15.1k
    break;
2839
2840
15.1k
  case AARCH64_OPND_SVE_ASIMM:
2841
14.1k
    min_value = -128;
2842
14.1k
    goto sve_aimm;
2843
2844
69
  case AARCH64_OPND_SVE_I1_HALF_ONE:
2845
69
    assert (opnd->imm.is_fp);
2846
69
    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
69
    break;
2853
2854
229
  case AARCH64_OPND_SVE_I1_HALF_TWO:
2855
229
    assert (opnd->imm.is_fp);
2856
229
    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
229
    break;
2863
2864
1.07k
  case AARCH64_OPND_SVE_I1_ZERO_ONE:
2865
1.07k
    assert (opnd->imm.is_fp);
2866
1.07k
    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.07k
    break;
2873
2874
1.07k
  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.08k
  case AARCH64_OPND_SVE_LIMM_MOV:
2888
3.08k
    {
2889
3.08k
      int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
2890
3.08k
      uint64_t uimm = opnd->imm.value;
2891
3.08k
      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.08k
      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.08k
    }
2904
3.08k
    break;
2905
2906
6.80k
  case AARCH64_OPND_SVE_PATTERN_SCALED:
2907
6.80k
    assert (opnd->shifter.kind == AARCH64_MOD_MUL);
2908
6.80k
    if (!value_in_range_p (opnd->shifter.amount, 1, 16))
2909
0
      {
2910
0
        set_multiplier_out_of_range_error (mismatch_detail, idx, 1, 16);
2911
0
        return false;
2912
0
      }
2913
6.80k
    break;
2914
2915
6.80k
  case AARCH64_OPND_SVE_SHLIMM_PRED:
2916
1.90k
  case AARCH64_OPND_SVE_SHLIMM_UNPRED:
2917
2.62k
  case AARCH64_OPND_SVE_SHLIMM_UNPRED_22:
2918
2.62k
    size = aarch64_get_qualifier_esize (opnds[idx - 1].qualifier);
2919
2.62k
    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.62k
    break;
2926
2927
2.62k
  case AARCH64_OPND_SME_SHRIMM3:
2928
338
  case AARCH64_OPND_SME_SHRIMM4:
2929
338
    size = 1 << get_operand_fields_width (get_operand_from_code (type));
2930
338
    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
338
    break;
2936
2937
338
  case AARCH64_OPND_SME_SHRIMM5:
2938
1.67k
  case AARCH64_OPND_SVE_SHRIMM_PRED:
2939
3.64k
  case AARCH64_OPND_SVE_SHRIMM_UNPRED:
2940
7.84k
  case AARCH64_OPND_SVE_SHRIMM_UNPRED_22:
2941
7.84k
    num = (type == AARCH64_OPND_SVE_SHRIMM_UNPRED_22) ? 2 : 1;
2942
7.84k
    size = aarch64_get_qualifier_esize (opnds[idx - num].qualifier);
2943
7.84k
    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
7.84k
    break;
2949
2950
7.84k
  case AARCH64_OPND_SME_ZT0_INDEX:
2951
97
    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
97
    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
97
    break;
2963
2964
132
  case AARCH64_OPND_SME_ZT0_INDEX_MUL_VL:
2965
132
    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
132
    break;
2971
2972
331k
  default:
2973
331k
    break;
2974
3.01M
  }
2975
2.99M
      break;
2976
2977
2.99M
    case AARCH64_OPND_CLASS_SYSTEM:
2978
59.8k
      switch (type)
2979
59.8k
  {
2980
223
  case AARCH64_OPND_PSTATEFIELD:
2981
829
    for (i = 0; aarch64_pstatefields[i].name; ++i)
2982
829
      if (aarch64_pstatefields[i].value == opnd->pstatefield)
2983
223
        break;
2984
223
    assert (aarch64_pstatefields[i].name);
2985
223
    assert (idx == 0 && opnds[1].type == AARCH64_OPND_UIMM4);
2986
223
    max_value = F_GET_REG_MAX_VALUE (aarch64_pstatefields[i].flags);
2987
223
    if (opnds[1].imm.value < 0 || opnds[1].imm.value > max_value)
2988
23
      {
2989
23
        set_imm_out_of_range_error (mismatch_detail, 1, 0, max_value);
2990
23
        return false;
2991
23
      }
2992
200
    break;
2993
42.2k
  case AARCH64_OPND_PRFOP:
2994
42.2k
    if (opcode->iclass == ldst_regoff && opnd->prfop->value >= 24)
2995
952
      {
2996
952
        set_other_error (mismatch_detail, idx,
2997
952
             _("the register-index form of PRFM does"
2998
952
         " not accept opcodes in the range 24-31"));
2999
952
        return false;
3000
952
      }
3001
41.3k
    break;
3002
41.3k
  default:
3003
17.3k
    break;
3004
59.8k
  }
3005
58.9k
      break;
3006
3007
94.9k
    case AARCH64_OPND_CLASS_SIMD_ELEMENT:
3008
      /* Get the upper bound for the element index.  */
3009
94.9k
      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
6.77k
  num = aarch64_get_qualifier_nelem (opnds[0].qualifier)
3013
6.77k
        * aarch64_get_qualifier_esize (opnds[0].qualifier) / 2;
3014
88.2k
      else if (opcode->iclass == lut)
3015
3.49k
  {
3016
3.49k
    size = get_operand_fields_width (get_operand_from_code (type)) - 5;
3017
3.49k
    if (!check_reglane (opnd, mismatch_detail, idx, "v", 0, 31,
3018
3.49k
            0, (1 << size) - 1))
3019
0
      return 0;
3020
3.49k
    break;
3021
3.49k
  }
3022
84.7k
      else
3023
84.7k
  num = 16;
3024
91.4k
      num = num / aarch64_get_qualifier_esize (qualifier) - 1;
3025
91.4k
      assert (aarch64_get_qualifier_nelem (qualifier) == 1);
3026
3027
      /* Index out-of-range.  */
3028
91.4k
      if (!value_in_range_p (opnd->reglane.index, 0, num))
3029
673
  {
3030
673
    set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, num);
3031
673
    return false;
3032
673
  }
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
90.8k
      if (type == AARCH64_OPND_Em16
3042
42.9k
    && (qualifier == AARCH64_OPND_QLF_S_H
3043
8.10k
        || qualifier == AARCH64_OPND_QLF_S_2B)
3044
37.1k
    && !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
90.8k
      if (type == AARCH64_OPND_Em8
3050
3.03k
    && !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
90.8k
      break;
3056
3057
521k
    case AARCH64_OPND_CLASS_MODIFIED_REG:
3058
521k
      assert (idx == 1 || idx == 2);
3059
521k
      switch (type)
3060
521k
  {
3061
47.4k
  case AARCH64_OPND_Rm_EXT:
3062
47.4k
    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
47.4k
    if (!aarch64_stack_pointer_p (opnds + 0)
3074
46.2k
        && (idx != 2 || !aarch64_stack_pointer_p (opnds + 1)))
3075
44.2k
      {
3076
44.2k
        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
44.2k
        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
44.2k
      }
3089
47.4k
    assert (opnd->shifter.operator_present  /* Default to LSL.  */
3090
47.4k
      || opnd->shifter.kind == AARCH64_MOD_LSL);
3091
47.4k
    if (!value_in_range_p (opnd->shifter.amount, 0, 4))
3092
7.80k
      {
3093
7.80k
        set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, 4);
3094
7.80k
        return false;
3095
7.80k
      }
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
39.6k
    if (qualifier == AARCH64_OPND_QLF_X
3102
4.10k
        && opnd->shifter.kind != AARCH64_MOD_LSL
3103
4.10k
        && opnd->shifter.kind != AARCH64_MOD_UXTX
3104
1.96k
        && opnd->shifter.kind != AARCH64_MOD_SXTX)
3105
0
      {
3106
0
        set_other_error (mismatch_detail, idx, _("W register expected"));
3107
0
        return false;
3108
0
      }
3109
39.6k
    break;
3110
3111
472k
  case AARCH64_OPND_Rm_SFT:
3112
    /* ROR is not available to the shifted register operand in
3113
       arithmetic instructions.  */
3114
472k
    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
472k
    if (opnd->shifter.kind == AARCH64_MOD_ROR
3121
78.0k
        && 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
472k
    num = qualifier == AARCH64_OPND_QLF_W ? 31 : 63;
3128
472k
    if (!value_in_range_p (opnd->shifter.amount, 0, num))
3129
60.2k
      {
3130
60.2k
        set_sft_amount_out_of_range_error (mismatch_detail, idx, 0, num);
3131
60.2k
        return false;
3132
60.2k
      }
3133
412k
    break;
3134
3135
412k
  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
773
    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
773
    break;
3145
3146
773
  default:
3147
0
    break;
3148
521k
  }
3149
452k
      break;
3150
3151
1.64M
    default:
3152
1.64M
      break;
3153
16.5M
    }
3154
3155
16.4M
  return true;
3156
16.5M
}
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
7.15M
{
3173
7.15M
  int i;
3174
3175
7.15M
  DEBUG_TRACE ("enter");
3176
3177
7.15M
  i = inst->opcode->tied_operand;
3178
3179
7.15M
  if (i > 0)
3180
75.2k
    {
3181
      /* Check for tied_operands with specific opcode iclass.  */
3182
75.2k
      switch (inst->opcode->iclass)
3183
75.2k
        {
3184
        /* For SME LDR and STR instructions #imm must have the same numerical
3185
           value for both operands.
3186
        */
3187
900
        case sme_ldr:
3188
951
        case sme_str:
3189
951
          assert (inst->operands[0].type == AARCH64_OPND_SME_ZA_array_off4);
3190
951
          assert (inst->operands[1].type == AARCH64_OPND_SME_ADDR_RI_U4xVL);
3191
951
          if (inst->operands[0].indexed_za.index.imm
3192
951
              != 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
951
          break;
3202
3203
74.3k
        default:
3204
74.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
74.3k
      enum aarch64_operand_class op_class
3212
74.3k
         = aarch64_get_operand_class (inst->operands[0].type);
3213
74.3k
      assert (aarch64_get_operand_class (inst->operands[i].type)
3214
74.3k
        == op_class);
3215
74.3k
      if (op_class == AARCH64_OPND_CLASS_SVE_REGLIST
3216
74.3k
    ? ((inst->operands[0].reglist.first_regno
3217
384
        != inst->operands[i].reglist.first_regno)
3218
384
       || (inst->operands[0].reglist.num_regs
3219
384
           != inst->operands[i].reglist.num_regs)
3220
384
       || (inst->operands[0].reglist.stride
3221
384
           != inst->operands[i].reglist.stride))
3222
74.3k
    : (inst->operands[0].reg.regno
3223
73.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
74.3k
      break;
3234
74.3k
    }
3235
75.2k
        }
3236
75.2k
    }
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
7.15M
  int invalid_count;
3249
7.15M
  if (match_operands_qualifier (inst, true /* update_p */,
3250
7.15M
        &invalid_count) == 0)
3251
39.1k
    {
3252
39.1k
      DEBUG_TRACE ("FAIL on operand qualifier matching");
3253
39.1k
      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
39.1k
      return false;
3264
39.1k
    }
3265
3266
  /* Match operands' constraint.  */
3267
23.5M
  for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
3268
23.5M
    {
3269
23.5M
      enum aarch64_opnd type = inst->opcode->operands[i];
3270
23.5M
      if (type == AARCH64_OPND_NIL)
3271
6.94M
  break;
3272
16.5M
      if (inst->operands[i].skip)
3273
0
  {
3274
0
    DEBUG_TRACE ("skip the incomplete operand %d", i);
3275
0
    continue;
3276
0
  }
3277
16.5M
      if (!operand_general_constraint_met_p (inst->operands, i, type,
3278
16.5M
               inst->opcode, mismatch_detail))
3279
169k
  {
3280
169k
    DEBUG_TRACE ("FAIL on operand %d", i);
3281
169k
    return false;
3282
169k
  }
3283
16.5M
    }
3284
3285
  /* Check constraints involving multiple operands.  */
3286
6.94M
  if (inst->opcode->flags & F_REQUIRES_SP)
3287
4.60k
    {
3288
4.60k
      bool sp_found = false;
3289
13.0k
      for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
3290
13.0k
  {
3291
13.0k
    enum aarch64_opnd type = inst->opcode->operands[i];
3292
13.0k
    if (type == AARCH64_OPND_NIL)
3293
4.22k
      break;
3294
8.85k
    if (aarch64_stack_pointer_p (&(inst->operands[i])))
3295
371
      {
3296
371
        sp_found = true;
3297
371
        break;
3298
371
      }
3299
8.85k
  }
3300
4.60k
      if (!sp_found)
3301
4.22k
  {
3302
4.22k
    set_other_error (mismatch_detail, -1,
3303
4.22k
         _("expected at least one stack pointer operand"));
3304
4.22k
    return false;
3305
4.22k
  }
3306
4.60k
    }
3307
3308
6.94M
  DEBUG_TRACE ("PASS");
3309
3310
6.94M
  return true;
3311
6.94M
}
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
85.6k
{
3325
85.6k
  int i;
3326
85.6k
  const aarch64_opcode *old = inst->opcode;
3327
3328
85.6k
  inst->opcode = opcode;
3329
3330
  /* Update the operand types.  */
3331
313k
  for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
3332
313k
    {
3333
313k
      inst->operands[i].type = opcode->operands[i];
3334
313k
      if (opcode->operands[i] == AARCH64_OPND_NIL)
3335
85.6k
  break;
3336
313k
    }
3337
3338
85.6k
  DEBUG_TRACE ("replace %s with %s", old->name, opcode->name);
3339
3340
85.6k
  return old;
3341
85.6k
}
3342
3343
int
3344
aarch64_operand_index (const enum aarch64_opnd *operands, enum aarch64_opnd operand)
3345
169k
{
3346
169k
  int i;
3347
201k
  for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
3348
201k
    if (operands[i] == operand)
3349
163k
      return i;
3350
37.4k
    else if (operands[i] == AARCH64_OPND_NIL)
3351
6.00k
      break;
3352
6.00k
  return -1;
3353
169k
}
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.25M
{
3392
4.25M
  const int has_zr = sp_reg_p ? 0 : 1;
3393
4.25M
  const int is_64 = aarch64_get_qualifier_esize (qualifier) == 4 ? 0 : 1;
3394
4.25M
  return int_reg[has_zr][is_64][regno];
3395
4.25M
}
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.48M
{
3402
1.48M
  const int has_zr = sp_reg_p ? 0 : 1;
3403
1.48M
  return int_reg[has_zr][1][regno];
3404
1.48M
}
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
142k
{
3412
142k
  switch (opnd->shifter.kind)
3413
142k
    {
3414
1.81k
    case AARCH64_MOD_UXTW:
3415
4.12k
    case AARCH64_MOD_SXTW:
3416
4.12k
      return get_int_reg_name (opnd->addr.offset.regno, AARCH64_OPND_QLF_W, 0);
3417
3418
133k
    case AARCH64_MOD_LSL:
3419
138k
    case AARCH64_MOD_SXTX:
3420
138k
      return get_int_reg_name (opnd->addr.offset.regno, AARCH64_OPND_QLF_X, 0);
3421
3422
0
    default:
3423
0
      abort ();
3424
142k
    }
3425
142k
}
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
123k
{
3433
123k
  assert (qualifier == AARCH64_OPND_QLF_S_S
3434
123k
    || qualifier == AARCH64_OPND_QLF_S_D);
3435
123k
  return sve_reg[qualifier == AARCH64_OPND_QLF_S_D][regno];
3436
123k
}
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.07k
{
3469
3.07k
  uint64_t imm = 0;
3470
3.07k
  uint32_t imm8_7, imm8_6_0, imm8_6, imm8_6_repl4;
3471
3472
3.07k
  imm8_7 = (imm8 >> 7) & 0x01;  /* imm8<7>   */
3473
3.07k
  imm8_6_0 = imm8 & 0x7f; /* imm8<6:0> */
3474
3.07k
  imm8_6 = imm8_6_0 >> 6; /* imm8<6>   */
3475
3.07k
  imm8_6_repl4 = (imm8_6 << 3) | (imm8_6 << 2)
3476
3.07k
    | (imm8_6 << 1) | imm8_6; /* Replicate(imm8<6>,4) */
3477
3.07k
  if (size == 8)
3478
570
    {
3479
570
      imm = (imm8_7 << (63-32))   /* imm8<7>  */
3480
570
  | ((imm8_6 ^ 1) << (62-32)) /* NOT(imm8<6)  */
3481
570
  | (imm8_6_repl4 << (58-32)) | (imm8_6 << (57-32))
3482
570
  | (imm8_6 << (56-32)) | (imm8_6 << (55-32)) /* Replicate(imm8<6>,7) */
3483
570
  | (imm8_6_0 << (48-32));  /* imm8<6>:imm8<5:0>    */
3484
570
      imm <<= 32;
3485
570
    }
3486
2.50k
  else if (size == 4 || size == 2)
3487
2.50k
    {
3488
2.50k
      imm = (imm8_7 << 31)  /* imm8<7>              */
3489
2.50k
  | ((imm8_6 ^ 1) << 30)  /* NOT(imm8<6>)         */
3490
2.50k
  | (imm8_6_repl4 << 26)  /* Replicate(imm8<6>,4) */
3491
2.50k
  | (imm8_6_0 << 19); /* imm8<6>:imm8<5:0>    */
3492
2.50k
    }
3493
0
  else
3494
0
    {
3495
      /* An unsupported size.  */
3496
0
      assert (0);
3497
0
    }
3498
3499
3.07k
  return imm;
3500
3.07k
}
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
10.5M
{
3507
10.5M
  const char *txt;
3508
10.5M
  va_list ap;
3509
3510
10.5M
  va_start (ap, fmt);
3511
10.5M
  txt = styler->apply_style (styler, dis_style_register, fmt, ap);
3512
10.5M
  va_end (ap);
3513
3514
10.5M
  return txt;
3515
10.5M
}
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.30M
{
3522
4.30M
  const char *txt;
3523
4.30M
  va_list ap;
3524
3525
4.30M
  va_start (ap, fmt);
3526
4.30M
  txt = styler->apply_style (styler, dis_style_immediate, fmt, ap);
3527
4.30M
  va_end (ap);
3528
3529
4.30M
  return txt;
3530
4.30M
}
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
714k
{
3537
714k
  const char *txt;
3538
714k
  va_list ap;
3539
3540
714k
  va_start (ap, fmt);
3541
714k
  txt = styler->apply_style (styler, dis_style_sub_mnemonic, fmt, ap);
3542
714k
  va_end (ap);
3543
3544
714k
  return txt;
3545
714k
}
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.25M
{
3552
1.25M
  const char *txt;
3553
1.25M
  va_list ap;
3554
3555
1.25M
  va_start (ap, fmt);
3556
1.25M
  txt = styler->apply_style (styler, dis_style_address, fmt, ap);
3557
1.25M
  va_end (ap);
3558
3559
1.25M
  return txt;
3560
1.25M
}
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
372k
{
3569
372k
  const int mask = (prefix[0] == 'p' ? 15 : 31);
3570
372k
  const int num_regs = opnd->reglist.num_regs;
3571
372k
  const int stride = opnd->reglist.stride;
3572
372k
  const int first_reg = opnd->reglist.first_regno;
3573
372k
  const int last_reg = (first_reg + (num_regs - 1) * stride) & mask;
3574
372k
  const char *qlf_name = aarch64_get_qualifier_name (opnd->qualifier);
3575
372k
  char tb[16];  /* Temporary buffer.  */
3576
3577
372k
  assert (opnd->type != AARCH64_OPND_LEt || opnd->reglist.has_index);
3578
372k
  assert (num_regs >= 1 && num_regs <= 4);
3579
3580
  /* Prepare the index if any.  */
3581
372k
  if (opnd->reglist.has_index)
3582
    /* PR 21096: The %100 is to silence a warning about possible truncation.  */
3583
18.2k
    snprintf (tb, sizeof (tb), "[%s]",
3584
18.2k
        style_imm (styler, "%" PRIi64, (opnd->reglist.index % 100)));
3585
354k
  else
3586
354k
    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
372k
  if (stride == 1 && num_regs > 1)
3592
114k
    if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
3593
277
      snprintf (buf, size, "{%s-%s}%s",
3594
277
    style_reg (styler, "%s%d", prefix, first_reg),
3595
277
    style_reg (styler, "%s%d", prefix, last_reg), tb);
3596
114k
    else
3597
114k
      snprintf (buf, size, "{%s-%s}%s",
3598
114k
    style_reg (styler, "%s%d.%s", prefix, first_reg, qlf_name),
3599
114k
    style_reg (styler, "%s%d.%s", prefix, last_reg, qlf_name), tb);
3600
258k
  else
3601
258k
    {
3602
258k
      const int reg0 = first_reg;
3603
258k
      const int reg1 = (first_reg + stride) & mask;
3604
258k
      const int reg2 = (first_reg + stride * 2) & mask;
3605
258k
      const int reg3 = (first_reg + stride * 3) & mask;
3606
3607
258k
      switch (num_regs)
3608
258k
  {
3609
247k
  case 1:
3610
247k
    snprintf (buf, size, "{%s}%s",
3611
247k
        style_reg (styler, "%s%d.%s", prefix, reg0, qlf_name),
3612
247k
        tb);
3613
247k
    break;
3614
7.39k
  case 2:
3615
7.39k
    snprintf (buf, size, "{%s, %s}%s",
3616
7.39k
        style_reg (styler, "%s%d.%s", prefix, reg0, qlf_name),
3617
7.39k
        style_reg (styler, "%s%d.%s", prefix, reg1, qlf_name),
3618
7.39k
        tb);
3619
7.39k
    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.61k
  case 4:
3628
3.61k
    snprintf (buf, size, "{%s, %s, %s, %s}%s",
3629
3.61k
        style_reg (styler, "%s%d.%s", prefix, reg0, qlf_name),
3630
3.61k
        style_reg (styler, "%s%d.%s", prefix, reg1, qlf_name),
3631
3.61k
        style_reg (styler, "%s%d.%s", prefix, reg2, qlf_name),
3632
3.61k
        style_reg (styler, "%s%d.%s", prefix, reg3, qlf_name),
3633
3.61k
        tb);
3634
3.61k
    break;
3635
258k
  }
3636
258k
    }
3637
372k
}
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
804k
{
3648
804k
  if (opnd->addr.writeback)
3649
277k
    {
3650
277k
      if (opnd->addr.preind)
3651
142k
        {
3652
142k
    if (opnd->type == AARCH64_OPND_ADDR_SIMM10 && !opnd->addr.offset.imm)
3653
111
      snprintf (buf, size, "[%s]!", style_reg (styler, base));
3654
142k
          else
3655
142k
      snprintf (buf, size, "[%s, %s]!",
3656
142k
          style_reg (styler, base),
3657
142k
          style_imm (styler, "#%d", opnd->addr.offset.imm));
3658
142k
        }
3659
135k
      else
3660
135k
  snprintf (buf, size, "[%s], %s",
3661
135k
      style_reg (styler, base),
3662
135k
      style_imm (styler, "#%d", opnd->addr.offset.imm));
3663
277k
    }
3664
526k
  else
3665
526k
    {
3666
526k
      if (opnd->shifter.operator_present)
3667
84.6k
  {
3668
84.6k
    assert (opnd->shifter.kind == AARCH64_MOD_MUL_VL);
3669
84.6k
    snprintf (buf, size, "[%s, %s, %s]",
3670
84.6k
        style_reg (styler, base),
3671
84.6k
        style_imm (styler, "#%d", opnd->addr.offset.imm),
3672
84.6k
        style_sub_mnem (styler, "mul vl"));
3673
84.6k
  }
3674
441k
      else if (opnd->addr.offset.imm)
3675
360k
  snprintf (buf, size, "[%s, %s]",
3676
360k
      style_reg (styler, base),
3677
360k
      style_imm (styler, "#%d", opnd->addr.offset.imm));
3678
81.2k
      else
3679
81.2k
  snprintf (buf, size, "[%s]", style_reg (styler, base));
3680
526k
    }
3681
804k
}
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
249k
{
3692
249k
  char tb[32];      /* Temporary buffer.  */
3693
249k
  bool print_extend_p = true;
3694
249k
  bool print_amount_p = true;
3695
249k
  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
249k
  if (opnd->type == AARCH64_OPND_SVE_ADDR_ZX && offset != NULL
3700
12.6k
      && strcmp (offset,"xzr") == 0)
3701
350
    {
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
350
      snprintf (buf, size, "[%s]", style_reg (styler, base));
3706
350
    }
3707
249k
  else
3708
249k
    {
3709
249k
      if (!opnd->shifter.amount && (opnd->qualifier != AARCH64_OPND_QLF_S_B
3710
5.11k
            || !opnd->shifter.amount_present))
3711
115k
  {
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
115k
   print_amount_p = false;
3716
   /* Likewise, no need to print the shift operator LSL in such a
3717
      situation.  */
3718
115k
   if (opnd->shifter.kind == AARCH64_MOD_LSL)
3719
70.7k
     print_extend_p = false;
3720
115k
  }
3721
3722
      /* Prepare for the extend/shift.  */
3723
249k
      if (print_extend_p)
3724
178k
  {
3725
178k
    if (print_amount_p)
3726
134k
      snprintf (tb, sizeof (tb), ", %s %s",
3727
134k
          style_sub_mnem (styler, shift_name),
3728
134k
          style_imm (styler, "#%" PRIi64,
3729
    /* PR 21096: The %100 is to silence a warning about possible
3730
       truncation.  */
3731
134k
         (opnd->shifter.amount % 100)));
3732
44.5k
    else
3733
44.5k
      snprintf (tb, sizeof (tb), ", %s",
3734
44.5k
          style_sub_mnem (styler, shift_name));
3735
178k
  }
3736
70.7k
      else
3737
70.7k
  tb[0] = '\0';
3738
3739
249k
      snprintf (buf, size, "[%s, %s%s]", style_reg (styler, base),
3740
249k
    style_reg (styler, offset), tb);
3741
249k
    }
3742
249k
}
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
254
{
3757
254
  static const struct {
3758
254
    unsigned char mask;
3759
254
    char name[7];
3760
254
  } zan[] = {
3761
254
    { 0xff, "za" },
3762
254
    { 0x55, "za0.h" },
3763
254
    { 0xaa, "za1.h" },
3764
254
    { 0x11, "za0.s" },
3765
254
    { 0x22, "za1.s" },
3766
254
    { 0x44, "za2.s" },
3767
254
    { 0x88, "za3.s" },
3768
254
    { 0x01, "za0.d" },
3769
254
    { 0x02, "za1.d" },
3770
254
    { 0x04, "za2.d" },
3771
254
    { 0x08, "za3.d" },
3772
254
    { 0x10, "za4.d" },
3773
254
    { 0x20, "za5.d" },
3774
254
    { 0x40, "za6.d" },
3775
254
    { 0x80, "za7.d" },
3776
254
    { 0x00, " " },
3777
254
  };
3778
254
  int k;
3779
3780
254
  k = snprintf (buf, size, "{");
3781
2.18k
  for (unsigned int i = 0; i < ARRAY_SIZE (zan); i++)
3782
2.18k
    {
3783
2.18k
      if ((mask & zan[i].mask) == zan[i].mask)
3784
729
  {
3785
729
    mask &= ~zan[i].mask;
3786
729
    if (k > 1)
3787
478
      k += snprintf (buf + k, size - k, ", ");
3788
3789
729
    k += snprintf (buf + k, size - k, "%s",
3790
729
       style_reg (styler, zan[i].name));
3791
729
  }
3792
2.18k
      if (mask == 0)
3793
254
        break;
3794
2.18k
    }
3795
254
  snprintf (buf + k, size - k, "}");
3796
254
}
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
13.8M
{
3818
13.8M
  unsigned int i, num_conds;
3819
13.8M
  const char *name = NULL;
3820
13.8M
  const aarch64_opnd_info *opnd = opnds + idx;
3821
13.8M
  enum aarch64_modifier_kind kind;
3822
13.8M
  uint64_t addr, enum_value;
3823
3824
13.8M
  if (comment != NULL)
3825
13.8M
    {
3826
13.8M
      assert (comment_size > 0);
3827
13.8M
      comment[0] = '\0';
3828
13.8M
    }
3829
0
  else
3830
13.8M
    assert (comment_size == 0);
3831
3832
13.8M
  buf[0] = '\0';
3833
13.8M
  if (pcrel_p)
3834
13.8M
    *pcrel_p = 0;
3835
3836
13.8M
  switch (opnd->type)
3837
13.8M
    {
3838
1.06M
    case AARCH64_OPND_Rd:
3839
1.60M
    case AARCH64_OPND_Rn:
3840
1.71M
    case AARCH64_OPND_Rm:
3841
2.87M
    case AARCH64_OPND_Rt:
3842
3.13M
    case AARCH64_OPND_Rt2:
3843
3.27M
    case AARCH64_OPND_Rs:
3844
3.30M
    case AARCH64_OPND_Ra:
3845
3.30M
    case AARCH64_OPND_Rt_IN_SYS_ALIASES:
3846
3.30M
    case AARCH64_OPND_Rt_LS64:
3847
3.30M
    case AARCH64_OPND_Rt_SYS:
3848
3.30M
    case AARCH64_OPND_PAIRREG:
3849
3.30M
    case AARCH64_OPND_PAIRREG_OR_XZR:
3850
3.30M
    case AARCH64_OPND_SVE_Rm:
3851
3.30M
    case AARCH64_OPND_LSE128_Rt:
3852
3.31M
    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.31M
      if (opnd->type == AARCH64_OPND_Rt_SYS)
3857
327
  {
3858
327
    if (!opnd->present)
3859
8
      break;
3860
327
  }
3861
3.30M
      else if ((opnd->type == AARCH64_OPND_Rt_IN_SYS_ALIASES)
3862
33
         && (opnd->reg.regno
3863
33
       != get_optional_operand_default_value (opcode)))
3864
33
  {
3865
    /* Avoid printing an invalid additional value for Rt in SYS aliases such as
3866
       BRB, provide a helpful comment instead */
3867
33
    snprintf (comment, comment_size, "unpredictable encoding (Rt!=31): #%u", opnd->reg.regno);
3868
33
    break;
3869
33
  }
3870
      /* Omit the operand, e.g. RET.  */
3871
3.30M
      else if (optional_operand_p (opcode, idx)
3872
5.32k
         && (opnd->reg.regno
3873
5.32k
       == get_optional_operand_default_value (opcode)))
3874
2.10k
  break;
3875
3.31M
      assert (opnd->qualifier == AARCH64_OPND_QLF_W
3876
3.30M
        || opnd->qualifier == AARCH64_OPND_QLF_X);
3877
3.30M
      snprintf (buf, size, "%s",
3878
3.30M
    style_reg (styler, get_int_reg_name (opnd->reg.regno,
3879
3.30M
                 opnd->qualifier, 0)));
3880
3.30M
      break;
3881
3882
216k
    case AARCH64_OPND_Rd_SP:
3883
455k
    case AARCH64_OPND_Rn_SP:
3884
462k
    case AARCH64_OPND_Rt_SP:
3885
463k
    case AARCH64_OPND_SVE_Rn_SP:
3886
463k
    case AARCH64_OPND_Rm_SP:
3887
463k
      assert (opnd->qualifier == AARCH64_OPND_QLF_W
3888
463k
        || opnd->qualifier == AARCH64_OPND_QLF_X);
3889
463k
      snprintf (buf, size, "%s",
3890
463k
    style_reg (styler, get_int_reg_name (opnd->reg.regno,
3891
463k
                 opnd->qualifier, 1)));
3892
463k
      break;
3893
3894
23.3k
    case AARCH64_OPND_Rm_EXT:
3895
23.3k
      kind = opnd->shifter.kind;
3896
23.3k
      assert (idx == 1 || idx == 2);
3897
23.3k
      if ((aarch64_stack_pointer_p (opnds)
3898
22.4k
     || (idx == 2 && aarch64_stack_pointer_p (opnds + 1)))
3899
1.91k
    && ((opnd->qualifier == AARCH64_OPND_QLF_W
3900
895
         && opnds[0].qualifier == AARCH64_OPND_QLF_W
3901
512
         && kind == AARCH64_MOD_UXTW)
3902
1.83k
        || (opnd->qualifier == AARCH64_OPND_QLF_X
3903
1.01k
      && kind == AARCH64_MOD_UXTX)))
3904
891
  {
3905
    /* 'LSL' is the preferred form in this case.  */
3906
891
    kind = AARCH64_MOD_LSL;
3907
891
    if (opnd->shifter.amount == 0)
3908
431
      {
3909
        /* Shifter omitted.  */
3910
431
        snprintf (buf, size, "%s",
3911
431
      style_reg (styler,
3912
431
           get_int_reg_name (opnd->reg.regno,
3913
431
                 opnd->qualifier, 0)));
3914
431
        break;
3915
431
      }
3916
891
  }
3917
22.9k
      if (opnd->shifter.amount)
3918
17.3k
  snprintf (buf, size, "%s, %s %s",
3919
17.3k
      style_reg (styler, get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0)),
3920
17.3k
      style_sub_mnem (styler, aarch64_operand_modifiers[kind].name),
3921
17.3k
      style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
3922
5.60k
      else
3923
5.60k
  snprintf (buf, size, "%s, %s",
3924
5.60k
      style_reg (styler, get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0)),
3925
5.60k
      style_sub_mnem (styler, aarch64_operand_modifiers[kind].name));
3926
22.9k
      break;
3927
3928
293k
    case AARCH64_OPND_Rm_SFT:
3929
293k
      assert (opnd->qualifier == AARCH64_OPND_QLF_W
3930
293k
        || opnd->qualifier == AARCH64_OPND_QLF_X);
3931
293k
      if (opnd->shifter.amount == 0 && opnd->shifter.kind == AARCH64_MOD_LSL)
3932
32.8k
  snprintf (buf, size, "%s",
3933
32.8k
      style_reg (styler, get_int_reg_name (opnd->reg.regno,
3934
32.8k
                   opnd->qualifier, 0)));
3935
260k
      else
3936
260k
  snprintf (buf, size, "%s, %s %s",
3937
260k
      style_reg (styler, get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0)),
3938
260k
      style_sub_mnem (styler, aarch64_operand_modifiers[opnd->shifter.kind].name),
3939
260k
      style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
3940
293k
      break;
3941
3942
773
    case AARCH64_OPND_Rm_LSL:
3943
773
      assert (opnd->qualifier == AARCH64_OPND_QLF_X);
3944
773
      assert (opnd->shifter.kind == AARCH64_MOD_LSL);
3945
773
      if (opnd->shifter.amount == 0)
3946
251
  snprintf (buf, size, "%s",
3947
251
      style_reg (styler, get_int_reg_name (opnd->reg.regno,
3948
251
                   opnd->qualifier, 0)));
3949
522
      else
3950
522
  snprintf (buf, size, "%s, %s %s",
3951
522
      style_reg (styler, get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0)),
3952
522
      style_sub_mnem (styler, aarch64_operand_modifiers[opnd->shifter.kind].name),
3953
522
      style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
3954
773
      break;
3955
3956
106k
    case AARCH64_OPND_Fd:
3957
147k
    case AARCH64_OPND_Fn:
3958
196k
    case AARCH64_OPND_Fm:
3959
279k
    case AARCH64_OPND_Fa:
3960
713k
    case AARCH64_OPND_Ft:
3961
929k
    case AARCH64_OPND_Ft2:
3962
949k
    case AARCH64_OPND_Sd:
3963
970k
    case AARCH64_OPND_Sn:
3964
979k
    case AARCH64_OPND_Sm:
3965
979k
    case AARCH64_OPND_SVE_VZn:
3966
983k
    case AARCH64_OPND_SVE_Vd:
3967
984k
    case AARCH64_OPND_SVE_Vm:
3968
984k
    case AARCH64_OPND_SVE_Vn:
3969
984k
      snprintf (buf, size, "%s",
3970
984k
    style_reg (styler, "%s%d",
3971
984k
         aarch64_get_qualifier_name (opnd->qualifier),
3972
984k
         opnd->reg.regno));
3973
984k
      break;
3974
3975
9.97k
    case AARCH64_OPND_Va:
3976
270k
    case AARCH64_OPND_Vd:
3977
496k
    case AARCH64_OPND_Vn:
3978
649k
    case AARCH64_OPND_Vm:
3979
649k
      snprintf (buf, size, "%s",
3980
649k
    style_reg (styler, "v%d.%s", opnd->reg.regno,
3981
649k
         aarch64_get_qualifier_name (opnd->qualifier)));
3982
649k
      break;
3983
3984
1.78k
    case AARCH64_OPND_Ed:
3985
7.76k
    case AARCH64_OPND_En:
3986
40.0k
    case AARCH64_OPND_Em:
3987
83.0k
    case AARCH64_OPND_Em16:
3988
86.0k
    case AARCH64_OPND_Em8:
3989
86.0k
      snprintf (buf, size, "%s[%s]",
3990
86.0k
    style_reg (styler, "v%d.%s", opnd->reglane.regno,
3991
86.0k
         aarch64_get_qualifier_name (opnd->qualifier)),
3992
86.0k
    style_imm (styler, "%" PRIi64, opnd->reglane.index));
3993
86.0k
      break;
3994
3995
1.00k
    case AARCH64_OPND_Em_INDEX1_14:
3996
2.63k
    case AARCH64_OPND_Em_INDEX2_13:
3997
3.49k
    case AARCH64_OPND_Em_INDEX3_12:
3998
3.49k
      snprintf (buf, size, "%s[%s]",
3999
3.49k
    style_reg (styler, "v%d", opnd->reglane.regno),
4000
3.49k
    style_imm (styler, "%" PRIi64, opnd->reglane.index));
4001
3.49k
      break;
4002
4003
286
    case AARCH64_OPND_VdD1:
4004
919
    case AARCH64_OPND_VnD1:
4005
919
      snprintf (buf, size, "%s[%s]",
4006
919
    style_reg (styler, "v%d.d", opnd->reg.regno),
4007
919
    style_imm (styler, "1"));
4008
919
      break;
4009
4010
15.5k
    case AARCH64_OPND_LVn:
4011
19.0k
    case AARCH64_OPND_LVn_LUT:
4012
30.9k
    case AARCH64_OPND_LVt:
4013
32.7k
    case AARCH64_OPND_LVt_AL:
4014
50.8k
    case AARCH64_OPND_LEt:
4015
50.8k
      print_register_list (buf, size, opnd, "v", styler);
4016
50.8k
      break;
4017
4018
75.3k
    case AARCH64_OPND_SVE_Pd:
4019
676k
    case AARCH64_OPND_SVE_Pg3:
4020
677k
    case AARCH64_OPND_SVE_Pg4_5:
4021
694k
    case AARCH64_OPND_SVE_Pg4_10:
4022
702k
    case AARCH64_OPND_SVE_Pg4_16:
4023
709k
    case AARCH64_OPND_SVE_Pm:
4024
716k
    case AARCH64_OPND_SVE_Pn:
4025
718k
    case AARCH64_OPND_SVE_Pt:
4026
788k
    case AARCH64_OPND_SME_Pm:
4027
788k
      if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
4028
141k
  snprintf (buf, size, "%s",
4029
141k
      style_reg (styler, "p%d", opnd->reg.regno));
4030
646k
      else if (opnd->qualifier == AARCH64_OPND_QLF_P_Z
4031
381k
         || opnd->qualifier == AARCH64_OPND_QLF_P_M)
4032
559k
  snprintf (buf, size, "%s",
4033
559k
      style_reg (styler, "p%d/%s", opnd->reg.regno,
4034
559k
           aarch64_get_qualifier_name (opnd->qualifier)));
4035
86.9k
      else
4036
86.9k
  snprintf (buf, size, "%s",
4037
86.9k
      style_reg (styler, "p%d.%s", opnd->reg.regno,
4038
86.9k
           aarch64_get_qualifier_name (opnd->qualifier)));
4039
788k
      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.58k
    case AARCH64_OPND_SME_PNd3:
4046
29.4k
    case AARCH64_OPND_SME_PNg3:
4047
29.4k
    case AARCH64_OPND_SME_PNn:
4048
29.4k
      if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
4049
8.94k
  snprintf (buf, size, "%s",
4050
8.94k
      style_reg (styler, "pn%d", opnd->reg.regno));
4051
20.5k
      else if (opnd->qualifier == AARCH64_OPND_QLF_P_Z
4052
1.61k
         || opnd->qualifier == AARCH64_OPND_QLF_P_M)
4053
18.9k
  snprintf (buf, size, "%s",
4054
18.9k
      style_reg (styler, "pn%d/%s", opnd->reg.regno,
4055
18.9k
           aarch64_get_qualifier_name (opnd->qualifier)));
4056
1.61k
      else
4057
1.61k
  snprintf (buf, size, "%s",
4058
1.61k
      style_reg (styler, "pn%d.%s", opnd->reg.regno,
4059
1.61k
           aarch64_get_qualifier_name (opnd->qualifier)));
4060
29.4k
      break;
4061
4062
772
    case AARCH64_OPND_SME_Pdx2:
4063
877
    case AARCH64_OPND_SME_PdxN:
4064
877
      print_register_list (buf, size, opnd, "p", styler);
4065
877
      break;
4066
4067
105
    case AARCH64_OPND_SME_PNn3_INDEX1:
4068
148
    case AARCH64_OPND_SME_PNn3_INDEX2:
4069
148
      snprintf (buf, size, "%s[%s]",
4070
148
    style_reg (styler, "pn%d", opnd->reglane.regno),
4071
148
    style_imm (styler, "%" PRIi64, opnd->reglane.index));
4072
148
      break;
4073
4074
7.53k
    case AARCH64_OPND_SVE_Za_5:
4075
15.7k
    case AARCH64_OPND_SVE_Za_16:
4076
403k
    case AARCH64_OPND_SVE_Zd:
4077
442k
    case AARCH64_OPND_SVE_Zm_5:
4078
725k
    case AARCH64_OPND_SVE_Zm_16:
4079
1.15M
    case AARCH64_OPND_SVE_Zn:
4080
1.15M
    case AARCH64_OPND_SVE_Zt:
4081
1.16M
    case AARCH64_OPND_SME_Zm:
4082
1.16M
    case AARCH64_OPND_SME_Zm_17:
4083
1.17M
    case AARCH64_OPND_SME_Zn_6_3:
4084
1.18M
    case AARCH64_OPND_SME_Zm_17_3:
4085
1.18M
      if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
4086
3.03k
       snprintf (buf, size, "%s", style_reg (styler, "z%d", opnd->reg.regno));
4087
1.18M
      else
4088
1.18M
       snprintf (buf, size, "%s",
4089
1.18M
     style_reg (styler, "z%d.%s", opnd->reg.regno,
4090
1.18M
          aarch64_get_qualifier_name (opnd->qualifier)));
4091
1.18M
      break;
4092
4093
12.0k
    case AARCH64_OPND_SVE_ZnxN:
4094
260k
    case AARCH64_OPND_SVE_ZtxN:
4095
279k
    case AARCH64_OPND_SME_Zdnx2:
4096
285k
    case AARCH64_OPND_SME_Zdnx4:
4097
286k
    case AARCH64_OPND_SME_Znx2_6_3:
4098
286k
    case AARCH64_OPND_SME_Zmx2_17_3:
4099
289k
    case AARCH64_OPND_SME_Zmx2:
4100
289k
    case AARCH64_OPND_SME_Zmx4:
4101
289k
    case AARCH64_OPND_SME_Zmx2_INDEX_22:
4102
305k
    case AARCH64_OPND_SME_Znx2:
4103
305k
    case AARCH64_OPND_SME_Znx2_BIT_INDEX:
4104
309k
    case AARCH64_OPND_SME_Znx4:
4105
309k
    case AARCH64_OPND_SME_Zn7xN_UNTYPED:
4106
317k
    case AARCH64_OPND_SME_Ztx2_STRIDED:
4107
320k
    case AARCH64_OPND_SME_Ztx4_STRIDED:
4108
320k
      print_register_list (buf, size, opnd, "z", styler);
4109
320k
      break;
4110
4111
427
    case AARCH64_OPND_SVE_Zm1_23_INDEX:
4112
1.51k
    case AARCH64_OPND_SVE_Zm2_22_INDEX:
4113
5.90k
    case AARCH64_OPND_SVE_Zm3_INDEX:
4114
13.7k
    case AARCH64_OPND_SVE_Zm3_22_INDEX:
4115
13.9k
    case AARCH64_OPND_SVE_Zm3_19_INDEX:
4116
14.9k
    case AARCH64_OPND_SVE_Zm3_12_INDEX:
4117
21.0k
    case AARCH64_OPND_SVE_Zm3_11_INDEX:
4118
24.8k
    case AARCH64_OPND_SVE_Zm3_10_INDEX:
4119
28.2k
    case AARCH64_OPND_SVE_Zm4_11_INDEX:
4120
33.0k
    case AARCH64_OPND_SVE_Zm4_INDEX:
4121
33.8k
    case AARCH64_OPND_SVE_Zn_INDEX:
4122
38.0k
    case AARCH64_OPND_SME_Zk_INDEX:
4123
38.3k
    case AARCH64_OPND_SME_Zm_INDEX1:
4124
40.9k
    case AARCH64_OPND_SME_Zm_INDEX2:
4125
41.0k
    case AARCH64_OPND_SME_Zm_INDEX2_3:
4126
42.8k
    case AARCH64_OPND_SME_Zm_INDEX3_1:
4127
45.0k
    case AARCH64_OPND_SME_Zm_INDEX3_2:
4128
45.7k
    case AARCH64_OPND_SME_Zm_INDEX3_3:
4129
50.1k
    case AARCH64_OPND_SME_Zm_INDEX3_10:
4130
50.5k
    case AARCH64_OPND_SVE_Zn_5_INDEX:
4131
52.5k
    case AARCH64_OPND_SME_Zm_INDEX4_1:
4132
53.4k
    case AARCH64_OPND_SME_Zm_INDEX4_2:
4133
69.0k
    case AARCH64_OPND_SME_Zm_INDEX4_3:
4134
74.4k
    case AARCH64_OPND_SME_Zm_INDEX4_10:
4135
74.7k
    case AARCH64_OPND_SME_Zn_INDEX1_16:
4136
75.0k
    case AARCH64_OPND_SME_Zn_INDEX2_15:
4137
75.5k
    case AARCH64_OPND_SME_Zn_INDEX2_16:
4138
75.6k
    case AARCH64_OPND_SME_Zn_INDEX2_19:
4139
75.7k
    case AARCH64_OPND_SME_Zn_INDEX3_14:
4140
76.0k
    case AARCH64_OPND_SME_Zn_INDEX3_15:
4141
76.2k
    case AARCH64_OPND_SME_Zn_INDEX4_14:
4142
76.2k
      snprintf (buf, size, "%s[%s]",
4143
76.2k
    (opnd->qualifier == AARCH64_OPND_QLF_NIL
4144
76.2k
     ? style_reg (styler, "z%d", opnd->reglane.regno)
4145
76.2k
     : style_reg (styler, "z%d.%s", opnd->reglane.regno,
4146
67.9k
            aarch64_get_qualifier_name (opnd->qualifier))),
4147
76.2k
    style_imm (styler, "%" PRIi64, opnd->reglane.index));
4148
76.2k
      break;
4149
4150
85
    case AARCH64_OPND_SVE_Zn0_INDEX:
4151
177
    case AARCH64_OPND_SVE_Zn1_17_INDEX:
4152
302
    case AARCH64_OPND_SVE_Zn2_18_INDEX:
4153
397
    case AARCH64_OPND_SVE_Zn3_22_INDEX:
4154
503
    case AARCH64_OPND_SVE_Zd0_INDEX:
4155
607
    case AARCH64_OPND_SVE_Zd1_17_INDEX:
4156
694
    case AARCH64_OPND_SVE_Zd2_18_INDEX:
4157
721
    case AARCH64_OPND_SVE_Zd3_22_INDEX:
4158
721
      if (opnd->reglane.index == 0)
4159
280
  snprintf (buf, size, "%s", style_reg (styler, "z%d", opnd->reg.regno));
4160
441
      else
4161
441
  snprintf (buf, size, "%s[%s]",
4162
441
      style_reg (styler, "z%d", opnd->reglane.regno),
4163
441
      style_imm (styler, "%" PRIi64, opnd->reglane.index));
4164
721
      break;
4165
4166
1.76k
    case AARCH64_OPND_SME_ZAda_1b:
4167
66.8k
    case AARCH64_OPND_SME_ZAda_2b:
4168
83.5k
    case AARCH64_OPND_SME_ZAda_3b:
4169
83.5k
      snprintf (buf, size, "%s",
4170
83.5k
    style_reg (styler, "za%d.%s", opnd->reg.regno,
4171
83.5k
         aarch64_get_qualifier_name (opnd->qualifier)));
4172
83.5k
      break;
4173
4174
524
    case AARCH64_OPND_SME_ZA_HV_idx_src:
4175
2.64k
    case AARCH64_OPND_SME_ZA_HV_idx_srcxN:
4176
37.2k
    case AARCH64_OPND_SME_ZA_HV_idx_dest:
4177
38.1k
    case AARCH64_OPND_SME_ZA_HV_idx_destxN:
4178
81.5k
    case AARCH64_OPND_SME_ZA_HV_idx_ldstr:
4179
81.7k
    case AARCH64_OPND_SME_ZA_array_vrsb_1:
4180
81.7k
    case AARCH64_OPND_SME_ZA_array_vrsh_1:
4181
81.7k
    case AARCH64_OPND_SME_ZA_array_vrss_1:
4182
82.0k
    case AARCH64_OPND_SME_ZA_array_vrsd_1:
4183
82.2k
    case AARCH64_OPND_SME_ZA_array_vrsb_2:
4184
82.3k
    case AARCH64_OPND_SME_ZA_array_vrsh_2:
4185
82.5k
    case AARCH64_OPND_SME_ZA_array_vrss_2:
4186
82.7k
    case AARCH64_OPND_SME_ZA_array_vrsd_2:
4187
83.5k
    case AARCH64_OPND_SME_ZA_ARRAY4:
4188
83.5k
      snprintf (buf, size, "%s%s[%s, %s%s%s%s%s]%s",
4189
83.5k
    opnd->type == AARCH64_OPND_SME_ZA_HV_idx_ldstr ? "{" : "",
4190
83.5k
    style_reg (styler, "za%d%c%s%s",
4191
83.5k
         opnd->indexed_za.regno,
4192
83.5k
         opnd->indexed_za.v == 1 ? 'v' : 'h',
4193
83.5k
         opnd->qualifier == AARCH64_OPND_QLF_NIL ? "" : ".",
4194
83.5k
         (opnd->qualifier == AARCH64_OPND_QLF_NIL
4195
83.5k
          ? ""
4196
83.5k
          : aarch64_get_qualifier_name (opnd->qualifier))),
4197
83.5k
    style_reg (styler, "w%d", opnd->indexed_za.index.regno),
4198
83.5k
    style_imm (styler, "%" PRIi64, opnd->indexed_za.index.imm),
4199
83.5k
    opnd->indexed_za.index.countm1 ? ":" : "",
4200
83.5k
    (opnd->indexed_za.index.countm1
4201
83.5k
     ? style_imm (styler, "%d",
4202
4.29k
            opnd->indexed_za.index.imm
4203
4.29k
            + opnd->indexed_za.index.countm1)
4204
83.5k
     : ""),
4205
83.5k
    opnd->indexed_za.group_size ? ", " : "",
4206
83.5k
    opnd->indexed_za.group_size == 2
4207
83.5k
    ? style_sub_mnem (styler, "vgx2")
4208
83.5k
    : opnd->indexed_za.group_size == 4
4209
83.5k
    ? style_sub_mnem (styler, "vgx4") : "",
4210
83.5k
    opnd->type == AARCH64_OPND_SME_ZA_HV_idx_ldstr ? "}" : "");
4211
83.5k
      break;
4212
4213
254
    case AARCH64_OPND_SME_list_of_64bit_tiles:
4214
254
      print_sme_za_list (buf, size, opnd->imm.value, styler);
4215
254
      break;
4216
4217
6.02k
    case AARCH64_OPND_SME_ZA_array_off1x4:
4218
10.9k
    case AARCH64_OPND_SME_ZA_array_off2x2:
4219
17.3k
    case AARCH64_OPND_SME_ZA_array_off2x4:
4220
26.9k
    case AARCH64_OPND_SME_ZA_array_off3_0:
4221
27.3k
    case AARCH64_OPND_SME_ZA_array_off3_5:
4222
47.4k
    case AARCH64_OPND_SME_ZA_array_off3x2:
4223
48.4k
    case AARCH64_OPND_SME_ZA_array_off4:
4224
48.4k
      snprintf (buf, size, "%s[%s, %s%s%s%s%s]",
4225
48.4k
    style_reg (styler, "za%s%s",
4226
48.4k
         opnd->qualifier == AARCH64_OPND_QLF_NIL ? "" : ".",
4227
48.4k
         (opnd->qualifier == AARCH64_OPND_QLF_NIL
4228
48.4k
          ? ""
4229
48.4k
          : aarch64_get_qualifier_name (opnd->qualifier))),
4230
48.4k
    style_reg (styler, "w%d", opnd->indexed_za.index.regno),
4231
48.4k
    style_imm (styler, "%" PRIi64, opnd->indexed_za.index.imm),
4232
48.4k
    opnd->indexed_za.index.countm1 ? ":" : "",
4233
48.4k
    (opnd->indexed_za.index.countm1
4234
48.4k
     ? style_imm (styler, "%d",
4235
37.5k
            opnd->indexed_za.index.imm
4236
37.5k
            + opnd->indexed_za.index.countm1)
4237
48.4k
     : ""),
4238
48.4k
    opnd->indexed_za.group_size ? ", " : "",
4239
48.4k
    opnd->indexed_za.group_size == 2
4240
48.4k
    ? style_sub_mnem (styler, "vgx2")
4241
48.4k
    : opnd->indexed_za.group_size == 4
4242
35.3k
    ? style_sub_mnem (styler, "vgx4") : "");
4243
48.4k
      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
3.46k
    case AARCH64_OPND_SME_PnT_Wm_imm:
4251
3.46k
      snprintf (buf, size, "%s[%s, %s]",
4252
3.46k
    style_reg (styler, "p%d.%s", opnd->indexed_za.regno,
4253
3.46k
         aarch64_get_qualifier_name (opnd->qualifier)),
4254
3.46k
    style_reg (styler, "w%d", opnd->indexed_za.index.regno),
4255
3.46k
    style_imm (styler, "%" PRIi64, opnd->indexed_za.index.imm));
4256
3.46k
      break;
4257
4258
31
    case AARCH64_OPND_SME_VLxN_10:
4259
1.61k
    case AARCH64_OPND_SME_VLxN_13:
4260
1.61k
      enum_value = opnd->imm.value;
4261
1.61k
      assert (enum_value < ARRAY_SIZE (aarch64_sme_vlxn_array));
4262
1.61k
      snprintf (buf, size, "%s",
4263
1.61k
    style_sub_mnem (styler, aarch64_sme_vlxn_array[enum_value]));
4264
1.61k
      break;
4265
4266
33
    case AARCH64_OPND_BRBOP:
4267
33
      enum_value = opnd->imm.value;
4268
33
      assert (enum_value < ARRAY_SIZE (aarch64_brbop_array));
4269
33
      snprintf (buf, size, "%s",
4270
33
    style_sub_mnem (styler, aarch64_brbop_array[enum_value]));
4271
33
      break;
4272
4273
4.49k
    case AARCH64_OPND_CRn:
4274
8.98k
    case AARCH64_OPND_CRm:
4275
8.98k
      snprintf (buf, size, "%s",
4276
8.98k
    style_reg (styler, "C%" PRIi64, opnd->imm.value));
4277
8.98k
      break;
4278
4279
9.03k
    case AARCH64_OPND_IDX:
4280
9.61k
    case AARCH64_OPND_MASK:
4281
42.1k
    case AARCH64_OPND_IMM:
4282
64.7k
    case AARCH64_OPND_IMM_2:
4283
92.8k
    case AARCH64_OPND_WIDTH:
4284
97.3k
    case AARCH64_OPND_UIMM3_OP1:
4285
101k
    case AARCH64_OPND_UIMM3_OP2:
4286
245k
    case AARCH64_OPND_BIT_NUM:
4287
252k
    case AARCH64_OPND_IMM_VLSL:
4288
264k
    case AARCH64_OPND_IMM_VLSR:
4289
264k
    case AARCH64_OPND_SHLL_IMM:
4290
264k
    case AARCH64_OPND_IMM0:
4291
264k
    case AARCH64_OPND_IMMR:
4292
267k
    case AARCH64_OPND_IMMS:
4293
1.89M
    case AARCH64_OPND_UNDEFINED:
4294
1.89M
    case AARCH64_OPND_FBITS:
4295
1.89M
    case AARCH64_OPND_TME_UIMM16:
4296
1.90M
    case AARCH64_OPND_SIMM5:
4297
1.90M
    case AARCH64_OPND_SME_SHRIMM3:
4298
1.91M
    case AARCH64_OPND_SME_SHRIMM4:
4299
1.91M
    case AARCH64_OPND_SME_SHRIMM5:
4300
1.91M
    case AARCH64_OPND_SVE_SHLIMM_PRED:
4301
1.91M
    case AARCH64_OPND_SVE_SHLIMM_UNPRED:
4302
1.91M
    case AARCH64_OPND_SVE_SHLIMM_UNPRED_22:
4303
1.91M
    case AARCH64_OPND_SVE_SHRIMM_PRED:
4304
1.91M
    case AARCH64_OPND_SVE_SHRIMM_UNPRED:
4305
1.92M
    case AARCH64_OPND_SVE_SHRIMM_UNPRED_22:
4306
1.92M
    case AARCH64_OPND_SVE_SIMM5:
4307
1.92M
    case AARCH64_OPND_SVE_SIMM5B:
4308
1.92M
    case AARCH64_OPND_SVE_SIMM6:
4309
1.92M
    case AARCH64_OPND_SVE_SIMM8:
4310
1.92M
    case AARCH64_OPND_SVE_UIMM3:
4311
1.94M
    case AARCH64_OPND_SVE_UIMM7:
4312
1.94M
    case AARCH64_OPND_SVE_UIMM8:
4313
1.94M
    case AARCH64_OPND_SVE_UIMM4:
4314
1.94M
    case AARCH64_OPND_SVE_UIMM8_53:
4315
1.95M
    case AARCH64_OPND_IMM_ROT1:
4316
1.96M
    case AARCH64_OPND_IMM_ROT2:
4317
1.96M
    case AARCH64_OPND_IMM_ROT3:
4318
1.96M
    case AARCH64_OPND_SVE_IMM_ROT1:
4319
1.97M
    case AARCH64_OPND_SVE_IMM_ROT2:
4320
1.97M
    case AARCH64_OPND_SVE_IMM_ROT3:
4321
1.97M
    case AARCH64_OPND_CSSC_SIMM8:
4322
1.97M
    case AARCH64_OPND_CSSC_UIMM8:
4323
1.97M
      snprintf (buf, size, "%s",
4324
1.97M
    style_imm (styler, "#%" PRIi64, opnd->imm.value));
4325
1.97M
      break;
4326
4327
69
    case AARCH64_OPND_SVE_I1_HALF_ONE:
4328
298
    case AARCH64_OPND_SVE_I1_HALF_TWO:
4329
1.37k
    case AARCH64_OPND_SVE_I1_ZERO_ONE:
4330
1.37k
      {
4331
1.37k
  single_conv_t c;
4332
1.37k
  c.i = opnd->imm.value;
4333
1.37k
  snprintf (buf, size, "%s", style_imm (styler, "#%.1f", c.f));
4334
1.37k
  break;
4335
298
      }
4336
4337
177
    case AARCH64_OPND_SVE_PATTERN:
4338
177
      if (optional_operand_p (opcode, idx)
4339
177
    && opnd->imm.value == get_optional_operand_default_value (opcode))
4340
57
  break;
4341
120
      enum_value = opnd->imm.value;
4342
120
      assert (enum_value < ARRAY_SIZE (aarch64_sve_pattern_array));
4343
120
      if (aarch64_sve_pattern_array[enum_value])
4344
46
  snprintf (buf, size, "%s",
4345
46
      style_reg (styler, aarch64_sve_pattern_array[enum_value]));
4346
74
      else
4347
74
  snprintf (buf, size, "%s",
4348
74
      style_imm (styler, "#%" PRIi64, opnd->imm.value));
4349
120
      break;
4350
4351
6.80k
    case AARCH64_OPND_SVE_PATTERN_SCALED:
4352
6.80k
      if (optional_operand_p (opcode, idx)
4353
6.80k
    && !opnd->shifter.operator_present
4354
1.12k
    && opnd->imm.value == get_optional_operand_default_value (opcode))
4355
491
  break;
4356
6.31k
      enum_value = opnd->imm.value;
4357
6.31k
      assert (enum_value < ARRAY_SIZE (aarch64_sve_pattern_array));
4358
6.31k
      if (aarch64_sve_pattern_array[opnd->imm.value])
4359
4.52k
  snprintf (buf, size, "%s",
4360
4.52k
      style_reg (styler,
4361
4.52k
           aarch64_sve_pattern_array[opnd->imm.value]));
4362
1.79k
      else
4363
1.79k
  snprintf (buf, size, "%s",
4364
1.79k
      style_imm (styler, "#%" PRIi64, opnd->imm.value));
4365
6.31k
      if (opnd->shifter.operator_present)
4366
5.68k
  {
4367
5.68k
    size_t len = strlen (buf);
4368
5.68k
    const char *shift_name
4369
5.68k
      = aarch64_operand_modifiers[opnd->shifter.kind].name;
4370
5.68k
    snprintf (buf + len, size - len, ", %s %s",
4371
5.68k
        style_sub_mnem (styler, shift_name),
4372
5.68k
        style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
4373
5.68k
  }
4374
6.31k
      break;
4375
4376
17.9k
    case AARCH64_OPND_SVE_PRFOP:
4377
17.9k
      enum_value = opnd->imm.value;
4378
17.9k
      assert (enum_value < ARRAY_SIZE (aarch64_sve_prfop_array));
4379
17.9k
      if (aarch64_sve_prfop_array[enum_value])
4380
11.4k
  snprintf (buf, size, "%s",
4381
11.4k
      style_reg (styler, aarch64_sve_prfop_array[enum_value]));
4382
6.50k
      else
4383
6.50k
  snprintf (buf, size, "%s",
4384
6.50k
      style_imm (styler, "#%" PRIi64, opnd->imm.value));
4385
17.9k
      break;
4386
4387
55.1k
    case AARCH64_OPND_IMM_MOV:
4388
55.1k
      switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
4389
55.1k
  {
4390
8.96k
  case 4: /* e.g. MOV Wd, #<imm32>.  */
4391
8.96k
      {
4392
8.96k
        int imm32 = opnd->imm.value;
4393
8.96k
        snprintf (buf, size, "%s",
4394
8.96k
      style_imm (styler, "#0x%-20x", imm32));
4395
8.96k
        snprintf (comment, comment_size, "#%d", imm32);
4396
8.96k
      }
4397
8.96k
    break;
4398
46.2k
  case 8: /* e.g. MOV Xd, #<imm64>.  */
4399
46.2k
    snprintf (buf, size, "%s", style_imm (styler, "#0x%-20" PRIx64,
4400
46.2k
            opnd->imm.value));
4401
46.2k
    snprintf (comment, comment_size, "#%" PRIi64, opnd->imm.value);
4402
46.2k
    break;
4403
0
  default:
4404
0
    snprintf (buf, size, "<invalid>");
4405
0
    break;
4406
55.1k
  }
4407
55.1k
      break;
4408
4409
55.1k
    case AARCH64_OPND_FPIMM0:
4410
562
      snprintf (buf, size, "%s", style_imm (styler, "#0.0"));
4411
562
      break;
4412
4413
144k
    case AARCH64_OPND_LIMM:
4414
355k
    case AARCH64_OPND_AIMM:
4415
380k
    case AARCH64_OPND_HALF:
4416
380k
    case AARCH64_OPND_SVE_INV_LIMM:
4417
396k
    case AARCH64_OPND_SVE_LIMM:
4418
400k
    case AARCH64_OPND_SVE_LIMM_MOV:
4419
400k
      if (opnd->shifter.amount)
4420
93.8k
  snprintf (buf, size, "%s, %s %s",
4421
93.8k
      style_imm (styler, "#0x%" PRIx64, opnd->imm.value),
4422
93.8k
      style_sub_mnem (styler, "lsl"),
4423
93.8k
      style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
4424
306k
      else
4425
306k
  snprintf (buf, size, "%s",
4426
306k
      style_imm (styler, "#0x%" PRIx64, opnd->imm.value));
4427
400k
      break;
4428
4429
853
    case AARCH64_OPND_SIMD_IMM:
4430
4.05k
    case AARCH64_OPND_SIMD_IMM_SFT:
4431
4.05k
      if ((! opnd->shifter.amount && opnd->shifter.kind == AARCH64_MOD_LSL)
4432
2.94k
    || opnd->shifter.kind == AARCH64_MOD_NONE)
4433
1.95k
  snprintf (buf, size, "%s",
4434
1.95k
      style_imm (styler, "#0x%" PRIx64, opnd->imm.value));
4435
2.09k
      else
4436
2.09k
  snprintf (buf, size, "%s, %s %s",
4437
2.09k
      style_imm (styler, "#0x%" PRIx64, opnd->imm.value),
4438
2.09k
      style_sub_mnem (styler, aarch64_operand_modifiers[opnd->shifter.kind].name),
4439
2.09k
      style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
4440
4.05k
      break;
4441
4442
1.38k
    case AARCH64_OPND_SVE_AIMM:
4443
8.29k
    case AARCH64_OPND_SVE_ASIMM:
4444
8.29k
      if (opnd->shifter.amount)
4445
183
  snprintf (buf, size, "%s, %s %s",
4446
183
      style_imm (styler, "#%" PRIi64, opnd->imm.value),
4447
183
      style_sub_mnem (styler, "lsl"),
4448
183
      style_imm (styler, "#%" PRIi64, opnd->shifter.amount));
4449
8.10k
      else
4450
8.10k
  snprintf (buf, size, "%s",
4451
8.10k
      style_imm (styler, "#%" PRIi64, opnd->imm.value));
4452
8.29k
      break;
4453
4454
124
    case AARCH64_OPND_FPIMM:
4455
2.36k
    case AARCH64_OPND_SIMD_FPIMM:
4456
3.07k
    case AARCH64_OPND_SVE_FPIMM8:
4457
3.07k
      switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
4458
3.07k
  {
4459
2.00k
  case 2: /* e.g. FMOV <Hd>, #<imm>.  */
4460
2.00k
      {
4461
2.00k
        half_conv_t c;
4462
2.00k
        c.i = expand_fp_imm (2, opnd->imm.value);
4463
2.00k
        snprintf (buf, size, "%s", style_imm (styler, "#%.18e", c.f));
4464
2.00k
      }
4465
2.00k
    break;
4466
495
  case 4: /* e.g. FMOV <Vd>.4S, #<imm>.  */
4467
495
      {
4468
495
        single_conv_t c;
4469
495
        c.i = expand_fp_imm (4, opnd->imm.value);
4470
495
        snprintf (buf, size, "%s", style_imm (styler, "#%.18e", c.f));
4471
495
      }
4472
495
    break;
4473
570
  case 8: /* e.g. FMOV <Sd>, #<imm>.  */
4474
570
      {
4475
570
        double_conv_t c;
4476
570
        c.i = expand_fp_imm (8, opnd->imm.value);
4477
570
        snprintf (buf, size, "%s", style_imm (styler, "#%.18e", c.d));
4478
570
      }
4479
570
    break;
4480
0
  default:
4481
0
    snprintf (buf, size, "<invalid>");
4482
0
    break;
4483
3.07k
  }
4484
3.07k
      break;
4485
4486
3.07k
    case AARCH64_OPND_CCMP_IMM:
4487
11.0k
    case AARCH64_OPND_NZCV:
4488
11.9k
    case AARCH64_OPND_EXCEPTION:
4489
12.2k
    case AARCH64_OPND_UIMM4:
4490
15.3k
    case AARCH64_OPND_UIMM4_ADDG:
4491
15.4k
    case AARCH64_OPND_UIMM7:
4492
18.4k
    case AARCH64_OPND_UIMM10:
4493
18.4k
      if (optional_operand_p (opcode, idx)
4494
303
    && (opnd->imm.value ==
4495
303
        (int64_t) get_optional_operand_default_value (opcode)))
4496
  /* Omit the operand, e.g. DCPS1.  */
4497
72
  break;
4498
18.3k
      snprintf (buf, size, "%s",
4499
18.3k
    style_imm (styler, "#0x%x", (unsigned int) opnd->imm.value));
4500
18.3k
      break;
4501
4502
18.2k
    case AARCH64_OPND_COND:
4503
18.6k
    case AARCH64_OPND_COND1:
4504
18.6k
      snprintf (buf, size, "%s",
4505
18.6k
    style_sub_mnem (styler, opnd->cond->names[0]));
4506
18.6k
      num_conds = ARRAY_SIZE (opnd->cond->names);
4507
37.3k
      for (i = 1; i < num_conds && opnd->cond->names[i]; ++i)
4508
18.6k
  {
4509
18.6k
    size_t len = comment != NULL ? strlen (comment) : 0;
4510
18.6k
    if (i == 1)
4511
12.9k
      snprintf (comment + len, comment_size - len, "%s = %s",
4512
12.9k
          opnd->cond->names[0], opnd->cond->names[i]);
4513
5.73k
    else
4514
5.73k
      snprintf (comment + len, comment_size - len, ", %s",
4515
5.73k
          opnd->cond->names[i]);
4516
18.6k
  }
4517
18.6k
      break;
4518
4519
130k
    case AARCH64_OPND_ADDR_ADRP:
4520
130k
      addr = ((pc + AARCH64_PCREL_OFFSET) & ~(uint64_t)0xfff)
4521
130k
  + opnd->imm.value;
4522
130k
      if (pcrel_p)
4523
130k
  *pcrel_p = 1;
4524
130k
      if (address)
4525
130k
  *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
130k
      snprintf (buf, size, "%s", style_addr (styler, "#0x%" PRIx64 , addr));
4531
130k
      break;
4532
4533
63.7k
    case AARCH64_OPND_ADDR_PCREL9:
4534
207k
    case AARCH64_OPND_ADDR_PCREL14:
4535
603k
    case AARCH64_OPND_ADDR_PCREL19:
4536
904k
    case AARCH64_OPND_ADDR_PCREL21:
4537
1.12M
    case AARCH64_OPND_ADDR_PCREL26:
4538
1.12M
      addr = pc + AARCH64_PCREL_OFFSET + opnd->imm.value;
4539
1.12M
      if (pcrel_p)
4540
1.12M
  *pcrel_p = 1;
4541
1.12M
      if (address)
4542
1.12M
  *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.12M
      snprintf (buf, size, "%s", style_addr (styler, "#0x%" PRIx64, addr));
4548
1.12M
      break;
4549
4550
196k
    case AARCH64_OPND_ADDR_SIMPLE:
4551
211k
    case AARCH64_OPND_SIMD_ADDR_SIMPLE:
4552
229k
    case AARCH64_OPND_SIMD_ADDR_POST:
4553
229k
      name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
4554
229k
      if (opnd->type == AARCH64_OPND_SIMD_ADDR_POST)
4555
17.7k
  {
4556
17.7k
    if (opnd->addr.offset.is_reg)
4557
15.0k
      snprintf (buf, size, "[%s], %s",
4558
15.0k
          style_reg (styler, name),
4559
15.0k
          style_reg (styler, "x%d", opnd->addr.offset.regno));
4560
2.73k
    else
4561
2.73k
      snprintf (buf, size, "[%s], %s",
4562
2.73k
          style_reg (styler, name),
4563
2.73k
          style_imm (styler, "#%d", opnd->addr.offset.imm));
4564
17.7k
  }
4565
211k
      else
4566
211k
  snprintf (buf, size, "[%s]", style_reg (styler, name));
4567
229k
      break;
4568
4569
26.5k
    case AARCH64_OPND_ADDR_REGOFF:
4570
37.7k
    case AARCH64_OPND_SVE_ADDR_RR:
4571
44.9k
    case AARCH64_OPND_SVE_ADDR_RR_LSL1:
4572
48.8k
    case AARCH64_OPND_SVE_ADDR_RR_LSL2:
4573
64.9k
    case AARCH64_OPND_SVE_ADDR_RR_LSL3:
4574
80.1k
    case AARCH64_OPND_SVE_ADDR_RR_LSL4:
4575
87.7k
    case AARCH64_OPND_SVE_ADDR_RM:
4576
91.6k
    case AARCH64_OPND_SVE_ADDR_RM_LSL1:
4577
95.9k
    case AARCH64_OPND_SVE_ADDR_RM_LSL2:
4578
99.3k
    case AARCH64_OPND_SVE_ADDR_RM_LSL3:
4579
99.3k
    case AARCH64_OPND_SVE_ADDR_RM_LSL4:
4580
114k
    case AARCH64_OPND_SVE_ADDR_RX:
4581
123k
    case AARCH64_OPND_SVE_ADDR_RX_LSL1:
4582
133k
    case AARCH64_OPND_SVE_ADDR_RX_LSL2:
4583
138k
    case AARCH64_OPND_SVE_ADDR_RX_LSL3:
4584
142k
    case AARCH64_OPND_SVE_ADDR_RX_LSL4:
4585
142k
      print_register_offset_address
4586
142k
  (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
4587
142k
   get_offset_int_reg_name (opnd), styler);
4588
142k
      break;
4589
4590
12.6k
    case AARCH64_OPND_SVE_ADDR_ZX:
4591
12.6k
      print_register_offset_address
4592
12.6k
  (buf, size, opnd,
4593
12.6k
   get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier),
4594
12.6k
   get_64bit_int_reg_name (opnd->addr.offset.regno, 0), styler);
4595
12.6k
      break;
4596
4597
19.9k
    case AARCH64_OPND_SVE_ADDR_RZ:
4598
22.6k
    case AARCH64_OPND_SVE_ADDR_RZ_LSL1:
4599
25.0k
    case AARCH64_OPND_SVE_ADDR_RZ_LSL2:
4600
27.6k
    case AARCH64_OPND_SVE_ADDR_RZ_LSL3:
4601
33.2k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW_14:
4602
68.6k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW_22:
4603
70.1k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW1_14:
4604
77.9k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW1_22:
4605
79.0k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW2_14:
4606
85.0k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW2_22:
4607
85.7k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW3_14:
4608
92.4k
    case AARCH64_OPND_SVE_ADDR_RZ_XTW3_22:
4609
92.4k
      print_register_offset_address
4610
92.4k
  (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
4611
92.4k
   get_addr_sve_reg_name (opnd->addr.offset.regno, opnd->qualifier),
4612
92.4k
   styler);
4613
92.4k
      break;
4614
4615
497k
    case AARCH64_OPND_ADDR_SIMM7:
4616
600k
    case AARCH64_OPND_ADDR_SIMM9:
4617
610k
    case AARCH64_OPND_ADDR_SIMM10:
4618
632k
    case AARCH64_OPND_ADDR_SIMM11:
4619
639k
    case AARCH64_OPND_ADDR_SIMM13:
4620
645k
    case AARCH64_OPND_RCPC3_ADDR_OFFSET:
4621
667k
    case AARCH64_OPND_ADDR_OFFSET:
4622
668k
    case AARCH64_OPND_RCPC3_ADDR_OPT_POSTIND:
4623
683k
    case AARCH64_OPND_RCPC3_ADDR_OPT_PREIND_WB:
4624
683k
    case AARCH64_OPND_RCPC3_ADDR_POSTIND:
4625
683k
    case AARCH64_OPND_RCPC3_ADDR_PREIND_WB:
4626
684k
    case AARCH64_OPND_SME_ADDR_RI_U4xVL:
4627
685k
    case AARCH64_OPND_SVE_ADDR_RI_S4x16:
4628
687k
    case AARCH64_OPND_SVE_ADDR_RI_S4x32:
4629
749k
    case AARCH64_OPND_SVE_ADDR_RI_S4xVL:
4630
760k
    case AARCH64_OPND_SVE_ADDR_RI_S4x2xVL:
4631
764k
    case AARCH64_OPND_SVE_ADDR_RI_S4x3xVL:
4632
771k
    case AARCH64_OPND_SVE_ADDR_RI_S4x4xVL:
4633
774k
    case AARCH64_OPND_SVE_ADDR_RI_S6xVL:
4634
777k
    case AARCH64_OPND_SVE_ADDR_RI_S9xVL:
4635
782k
    case AARCH64_OPND_SVE_ADDR_RI_U6:
4636
787k
    case AARCH64_OPND_SVE_ADDR_RI_U6x2:
4637
788k
    case AARCH64_OPND_SVE_ADDR_RI_U6x4:
4638
790k
    case AARCH64_OPND_SVE_ADDR_RI_U6x8:
4639
790k
      print_immediate_offset_address
4640
790k
  (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
4641
790k
   styler);
4642
790k
      break;
4643
4644
4.74k
    case AARCH64_OPND_SVE_ADDR_ZI_U5:
4645
10.6k
    case AARCH64_OPND_SVE_ADDR_ZI_U5x2:
4646
13.1k
    case AARCH64_OPND_SVE_ADDR_ZI_U5x4:
4647
14.3k
    case AARCH64_OPND_SVE_ADDR_ZI_U5x8:
4648
14.3k
      print_immediate_offset_address
4649
14.3k
  (buf, size, opnd,
4650
14.3k
   get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier),
4651
14.3k
   styler);
4652
14.3k
      break;
4653
4654
920
    case AARCH64_OPND_SVE_ADDR_ZZ_LSL:
4655
1.20k
    case AARCH64_OPND_SVE_ADDR_ZZ_SXTW:
4656
2.07k
    case AARCH64_OPND_SVE_ADDR_ZZ_UXTW:
4657
2.07k
      print_register_offset_address
4658
2.07k
  (buf, size, opnd,
4659
2.07k
   get_addr_sve_reg_name (opnd->addr.base_regno, opnd->qualifier),
4660
2.07k
   get_addr_sve_reg_name (opnd->addr.offset.regno, opnd->qualifier),
4661
2.07k
   styler);
4662
2.07k
      break;
4663
4664
216k
    case AARCH64_OPND_ADDR_UIMM12:
4665
216k
      name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
4666
216k
      if (opnd->addr.offset.imm)
4667
205k
  snprintf (buf, size, "[%s, %s]",
4668
205k
      style_reg (styler, name),
4669
205k
      style_imm (styler, "#%d", opnd->addr.offset.imm));
4670
11.3k
      else
4671
11.3k
  snprintf (buf, size, "[%s]", style_reg (styler, name));
4672
216k
      break;
4673
4674
10.3k
    case AARCH64_OPND_SYSREG:
4675
11.7k
    case AARCH64_OPND_SYSREG128:
4676
11.7k
      {
4677
11.7k
  int min_mismatch = 999;
4678
11.7k
  int best_index = -1;
4679
11.7k
  uint32_t op_flags = opnd->sysreg.flags;
4680
18.6M
  for (i = 0; aarch64_sys_regs[i].name; ++i)
4681
18.6M
    {
4682
18.6M
      const aarch64_sys_reg *sr = aarch64_sys_regs + i;
4683
4684
18.6M
      if (!(aarch64_sys_regs[i].value == opnd->sysreg.value)
4685
1.54k
    || aarch64_sys_reg_deprecated_p (aarch64_sys_regs[i].flags)
4686
1.54k
    || aarch64_sys_reg_alias_p (aarch64_sys_regs[i].flags))
4687
18.6M
        continue;
4688
4689
1.54k
      int mismatch_score = 0;
4690
1.54k
      if (!AARCH64_CPU_HAS_ALL_FEATURES (features, sr->features))
4691
865
        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.54k
      if (((sr->flags & F_REG_READ) && (op_flags & F_REG_WRITE))
4695
1.35k
    || ((sr->flags & F_REG_WRITE) && (op_flags & F_REG_READ)))
4696
217
        mismatch_score += 2;
4697
4698
1.54k
      if (mismatch_score < min_mismatch)
4699
1.54k
        {
4700
1.54k
    min_mismatch = mismatch_score;
4701
1.54k
    best_index = i;
4702
1.54k
    if (mismatch_score == 0)
4703
465
      break;
4704
1.54k
        }
4705
1.54k
    }
4706
11.7k
  if (best_index == -1)
4707
10.2k
    {
4708
      /* Use encoding-based name for unrecognised system register.  */
4709
10.2k
      unsigned int value = opnd->sysreg.value;
4710
10.2k
      snprintf (buf, size, "%s",
4711
10.2k
          style_reg (styler, "s%u_%u_c%u_c%u_%u",
4712
10.2k
         (value >> 14) & 0x3, (value >> 11) & 0x7,
4713
10.2k
         (value >> 7) & 0xf, (value >> 3) & 0xf,
4714
10.2k
         value & 0x7));
4715
10.2k
    }
4716
1.52k
  else
4717
1.52k
    {
4718
1.52k
      const aarch64_sys_reg *sr = aarch64_sys_regs + best_index;
4719
1.52k
      snprintf (buf, size, "%s", style_reg (styler, sr->name));
4720
4721
      /* Add a note if we violated read/write constraints.  */
4722
1.52k
      if (notes && min_mismatch)
4723
1.06k
        {
4724
1.06k
    if ((sr->flags & F_REG_READ) && (op_flags & F_REG_WRITE))
4725
171
      *notes = _("writing to a read-only register");
4726
893
    else if ((sr->flags & F_REG_WRITE) && (op_flags & F_REG_READ))
4727
28
      *notes = _("reading from a write-only register");
4728
1.06k
        }
4729
1.52k
    }
4730
11.7k
  break;
4731
10.3k
      }
4732
4733
200
    case AARCH64_OPND_PSTATEFIELD:
4734
799
      for (i = 0; aarch64_pstatefields[i].name; ++i)
4735
799
        if (aarch64_pstatefields[i].value == opnd->pstatefield)
4736
200
          {
4737
            /* PSTATEFIELD name is encoded partially in CRm[3:1] for SVCRSM,
4738
               SVCRZA and SVCRSMZA.  */
4739
200
            uint32_t flags = aarch64_pstatefields[i].flags;
4740
200
            if (flags & F_REG_IN_CRM
4741
0
                && (PSTATE_DECODE_CRM (opnd->sysreg.flags)
4742
0
                    != PSTATE_DECODE_CRM (flags)))
4743
0
              continue;
4744
200
            break;
4745
200
          }
4746
200
      assert (aarch64_pstatefields[i].name);
4747
200
      snprintf (buf, size, "%s",
4748
200
    style_reg (styler, aarch64_pstatefields[i].name));
4749
200
      break;
4750
4751
45
    case AARCH64_OPND_GIC:
4752
45
    case AARCH64_OPND_GICR:
4753
45
    case AARCH64_OPND_GSB:
4754
146
    case AARCH64_OPND_SYSREG_AT:
4755
209
    case AARCH64_OPND_SYSREG_DC:
4756
209
    case AARCH64_OPND_SYSREG_IC:
4757
416
    case AARCH64_OPND_SYSREG_TLBI:
4758
520
    case AARCH64_OPND_SYSREG_TLBIP:
4759
536
    case AARCH64_OPND_SYSREG_PLBI:
4760
536
    case AARCH64_OPND_SYSREG_SR:
4761
536
      snprintf (buf, size, "%s", style_reg (styler, opnd->sysins_op->name));
4762
536
      break;
4763
4764
55
    case AARCH64_OPND_BARRIER:
4765
266
    case AARCH64_OPND_BARRIER_DSB_NXS:
4766
266
      {
4767
266
  if (opnd->barrier->name[0] == '#')
4768
53
    snprintf (buf, size, "%s", style_imm (styler, opnd->barrier->name));
4769
213
  else
4770
213
    snprintf (buf, size, "%s",
4771
213
        style_sub_mnem (styler, opnd->barrier->name));
4772
266
      }
4773
266
      break;
4774
4775
119
    case AARCH64_OPND_BARRIER_ISB:
4776
      /* Operand can be omitted, e.g. in DCPS1.  */
4777
119
      if (! optional_operand_p (opcode, idx)
4778
119
    || (opnd->barrier->value
4779
119
        != get_optional_operand_default_value (opcode)))
4780
12
  snprintf (buf, size, "%s",
4781
12
      style_imm (styler, "#0x%x", opnd->barrier->value));
4782
119
      break;
4783
4784
41.1k
    case AARCH64_OPND_PRFOP:
4785
41.1k
      if ((opnd->prfop->name == NULL)
4786
34.9k
          || (opcode->iclass != ldst_pos && opnd->prfop->value == 0x18))
4787
17.3k
        snprintf (buf, size, "%s",
4788
17.3k
                  style_imm (styler, "#0x%02x", opnd->prfop->value));
4789
23.7k
      else
4790
23.7k
        snprintf (buf, size, "%s", style_sub_mnem (styler, opnd->prfop->name));
4791
41.1k
      break;
4792
4793
810
    case AARCH64_OPND_RPRFMOP:
4794
810
      enum_value = opnd->imm.value;
4795
810
      if (enum_value < ARRAY_SIZE (aarch64_rprfmop_array)
4796
810
    && aarch64_rprfmop_array[enum_value])
4797
127
  snprintf (buf, size, "%s",
4798
127
      style_reg (styler, aarch64_rprfmop_array[enum_value]));
4799
683
      else
4800
683
  snprintf (buf, size, "%s",
4801
683
      style_imm (styler, "#%" PRIi64, opnd->imm.value));
4802
810
      break;
4803
4804
169
    case AARCH64_OPND_BARRIER_PSB:
4805
169
      snprintf (buf, size, "%s", style_sub_mnem (styler, "csync"));
4806
169
      break;
4807
4808
0
    case AARCH64_OPND_X16:
4809
0
      snprintf (buf, size, "%s", style_reg (styler, "x16"));
4810
0
      break;
4811
4812
1.73k
    case AARCH64_OPND_SME_ZT0:
4813
1.73k
      snprintf (buf, size, "%s", style_reg (styler, "zt0"));
4814
1.73k
      break;
4815
4816
97
    case AARCH64_OPND_SME_ZT0_INDEX:
4817
97
      snprintf (buf, size, "%s[%s]", style_reg (styler, "zt0"),
4818
97
    style_imm (styler, "%d", (int) opnd->imm.value));
4819
97
      break;
4820
132
    case AARCH64_OPND_SME_ZT0_INDEX_MUL_VL:
4821
132
      snprintf (buf, size, "%s[%s, %s]", style_reg (styler, "zt0"),
4822
132
    style_imm (styler, "%d", (int) opnd->imm.value),
4823
132
    style_sub_mnem (styler, "mul vl"));
4824
132
      break;
4825
4826
54
    case AARCH64_OPND_SME_ZT0_LIST:
4827
54
      snprintf (buf, size, "{%s}", style_reg (styler, "zt0"));
4828
54
      break;
4829
4830
0
    case AARCH64_OPND_BARRIER_GCSB:
4831
0
      snprintf (buf, size, "%s", style_sub_mnem (styler, "dsync"));
4832
0
      break;
4833
4834
0
    case AARCH64_OPND_NOT_BALANCED_10:
4835
253
    case AARCH64_OPND_NOT_BALANCED_17:
4836
253
      if (opnd->imm.value)
4837
37
  snprintf (buf, size, "%s", style_sub_mnem (styler, "nb"));
4838
253
      break;
4839
4840
207
    case AARCH64_OPND_BTI_TARGET:
4841
207
      snprintf (buf, size, "%s",
4842
207
    style_sub_mnem (styler, opnd->hint_option->name));
4843
207
      break;
4844
4845
144
    case AARCH64_OPND_STSHH_POLICY:
4846
144
      snprintf (buf, size, "%s", style_sub_mnem (styler, opnd->hint_option->name));
4847
144
      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.16k
    case AARCH64_OPND_MOPS_ADDR_Rd:
4856
15.1k
    case AARCH64_OPND_MOPS_ADDR_Rs:
4857
15.1k
      snprintf (buf, size, "[%s]!",
4858
15.1k
    style_reg (styler,
4859
15.1k
         get_int_reg_name (opnd->reg.regno,
4860
15.1k
               AARCH64_OPND_QLF_X, 0)));
4861
15.1k
      break;
4862
4863
8.16k
    case AARCH64_OPND_MOPS_WB_Rn:
4864
8.16k
      snprintf (buf, size, "%s!",
4865
8.16k
    style_reg (styler, get_int_reg_name (opnd->reg.regno,
4866
8.16k
                 AARCH64_OPND_QLF_X, 0)));
4867
8.16k
      break;
4868
4869
0
    default:
4870
0
      snprintf (buf, size, "<invalid>");
4871
0
      break;
4872
13.8M
    }
4873
13.8M
}
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.54k
{
4916
1.54k
  return (reg_flags & F_DEPRECATED) != 0;
4917
1.54k
}
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.54k
{
4928
1.54k
  return (reg_flags & F_REG_ALIAS) != 0;
4929
1.54k
}
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
93.0k
#define BIT(INSN,BT)     (((INSN) >> (BT)) & 1)
5326
141k
#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
47.1k
{
5335
47.1k
  int t  = BITS (insn, 4, 0);
5336
47.1k
  int n  = BITS (insn, 9, 5);
5337
47.1k
  int t2 = BITS (insn, 14, 10);
5338
5339
47.1k
  if (BIT (insn, 23))
5340
13.6k
    {
5341
      /* Write back enabled.  */
5342
13.6k
      if ((t == n || t2 == n) && n != 31)
5343
1.19k
  return ERR_UND;
5344
13.6k
    }
5345
5346
45.9k
  if (BIT (insn, 22))
5347
45.9k
    {
5348
      /* Load */
5349
45.9k
      if (t == t2)
5350
5.20k
  return ERR_UND;
5351
45.9k
    }
5352
5353
40.7k
  return ERR_OK;
5354
45.9k
}
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
2.64k
{
5365
2.64k
  const aarch64_insn undef_pattern = 0x3;
5366
2.64k
  aarch64_insn value;
5367
5368
2.64k
  assert (inst->opcode);
5369
2.64k
  assert (inst->opcode->operands[2] == AARCH64_OPND_Em);
5370
2.64k
  value = encoding ? inst->value : insn;
5371
2.64k
  assert (value);
5372
5373
2.64k
  if (undef_pattern == extract_fields (value, 0, 2, FLD_sz, FLD_L))
5374
706
    return ERR_UND;
5375
5376
1.94k
  return ERR_OK;
5377
2.64k
}
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
9.47k
{
5392
9.47k
  int rd, rs, rn;
5393
5394
9.47k
  rd = inst->operands[0].reg.regno;
5395
9.47k
  rs = inst->operands[1].reg.regno;
5396
9.47k
  rn = inst->operands[2].reg.regno;
5397
9.47k
  if (rd == rs || rd == rn || rs == rn)
5398
1.44k
    {
5399
1.44k
      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5400
1.44k
      mismatch_detail->error
5401
1.44k
  = _("the three register operands must be distinct from one another");
5402
1.44k
      mismatch_detail->index = -1;
5403
1.44k
      return ERR_UND;
5404
1.44k
    }
5405
5406
8.03k
  return ERR_OK;
5407
9.47k
}
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
217
{
5422
217
  int rd, rn;
5423
5424
217
  rd = inst->operands[0].reg.regno;
5425
217
  rn = inst->operands[1].reg.regno;
5426
217
  if (rd == rn)
5427
82
    {
5428
82
      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5429
82
      mismatch_detail->error
5430
82
  = _("the two register operands must be distinct from each other");
5431
82
      mismatch_detail->index = -1;
5432
82
      return ERR_UND;
5433
82
    }
5434
5435
135
  return ERR_OK;
5436
217
}
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.02k
{
5444
9.02k
  insn_sequence->instr[insn_sequence->num_added_insns++] = *inst;
5445
9.02k
}
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
17.8k
{
5455
17.8k
  int num_req_entries = 0;
5456
5457
17.8k
  if (insn_sequence->instr)
5458
8.61k
    {
5459
8.61k
      XDELETE (insn_sequence->instr);
5460
8.61k
      insn_sequence->instr = NULL;
5461
8.61k
    }
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
17.8k
  if (inst && inst->opcode->constraints & C_SCAN_MOVPRFX)
5467
3.93k
    num_req_entries = 1;
5468
17.8k
  if (inst && (inst->opcode->constraints & C_SCAN_MOPS_PME) == C_SCAN_MOPS_P)
5469
4.68k
    num_req_entries = 2;
5470
5471
17.8k
  insn_sequence->num_added_insns = 0;
5472
17.8k
  insn_sequence->num_allocated_insns = num_req_entries;
5473
5474
17.8k
  if (num_req_entries != 0)
5475
8.61k
    {
5476
8.61k
      insn_sequence->instr = XCNEWVEC (aarch64_inst, num_req_entries);
5477
8.61k
      add_insn_to_sequence (inst, insn_sequence);
5478
8.61k
    }
5479
17.8k
}
5480
5481
/* Subroutine of verify_constraints.  Check whether the instruction
5482
   is part of a MOPS P/M/E sequence and, if so, whether sequencing
5483
   expectations are met.  Return true if the check passes, otherwise
5484
   describe the problem in MISMATCH_DETAIL.
5485
5486
   IS_NEW_SECTION is true if INST is assumed to start a new section.
5487
   The other arguments are as for verify_constraints.  */
5488
5489
static bool
5490
verify_mops_pme_sequence (const struct aarch64_inst *inst,
5491
        bool is_new_section,
5492
        aarch64_operand_error *mismatch_detail,
5493
        aarch64_instr_sequence *insn_sequence)
5494
223k
{
5495
223k
  const struct aarch64_opcode *opcode;
5496
223k
  const struct aarch64_inst *prev_insn;
5497
223k
  int i;
5498
5499
223k
  opcode = inst->opcode;
5500
223k
  if (insn_sequence->instr)
5501
8.14k
    prev_insn = insn_sequence->instr + (insn_sequence->num_added_insns - 1);
5502
215k
  else
5503
215k
    prev_insn = NULL;
5504
5505
223k
  if (prev_insn
5506
8.14k
      && (prev_insn->opcode->constraints & C_SCAN_MOPS_PME)
5507
4.26k
      && prev_insn->opcode != opcode - 1)
5508
3.86k
    {
5509
3.86k
      mismatch_detail->kind = AARCH64_OPDE_EXPECTED_A_AFTER_B;
5510
3.86k
      mismatch_detail->error = NULL;
5511
3.86k
      mismatch_detail->index = -1;
5512
3.86k
      mismatch_detail->data[0].s = prev_insn->opcode[1].name;
5513
3.86k
      mismatch_detail->data[1].s = prev_insn->opcode->name;
5514
3.86k
      mismatch_detail->non_fatal = true;
5515
3.86k
      return false;
5516
3.86k
    }
5517
5518
220k
  if (opcode->constraints & C_SCAN_MOPS_PME)
5519
3.47k
    {
5520
3.47k
      if (is_new_section || !prev_insn || prev_insn->opcode != opcode - 1)
5521
3.07k
  {
5522
3.07k
    mismatch_detail->kind = AARCH64_OPDE_A_SHOULD_FOLLOW_B;
5523
3.07k
    mismatch_detail->error = NULL;
5524
3.07k
    mismatch_detail->index = -1;
5525
3.07k
    mismatch_detail->data[0].s = opcode->name;
5526
3.07k
    mismatch_detail->data[1].s = opcode[-1].name;
5527
3.07k
    mismatch_detail->non_fatal = true;
5528
3.07k
    return false;
5529
3.07k
  }
5530
5531
793
      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
733
  if ((opcode->operands[i] == AARCH64_OPND_MOPS_ADDR_Rd
5535
333
       || opcode->operands[i] == AARCH64_OPND_MOPS_ADDR_Rs
5536
161
       || opcode->operands[i] == AARCH64_OPND_MOPS_WB_Rn)
5537
733
      && prev_insn->operands[i].reg.regno != inst->operands[i].reg.regno)
5538
340
    {
5539
340
      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5540
340
      if (opcode->operands[i] == AARCH64_OPND_MOPS_ADDR_Rd)
5541
228
        mismatch_detail->error = _("destination register differs from "
5542
112
           "preceding instruction");
5543
112
      else if (opcode->operands[i] == AARCH64_OPND_MOPS_ADDR_Rs)
5544
11
        mismatch_detail->error = _("source register differs from "
5545
101
           "preceding instruction");
5546
101
      else
5547
101
        mismatch_detail->error = _("size register differs from "
5548
340
           "preceding instruction");
5549
340
      mismatch_detail->index = i;
5550
340
      mismatch_detail->non_fatal = true;
5551
340
      return false;
5552
340
    }
5553
400
    }
5554
5555
216k
  return true;
5556
220k
}
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
6.18M
{
5578
6.18M
  assert (inst);
5579
6.18M
  assert (inst->opcode);
5580
5581
6.18M
  const struct aarch64_opcode *opcode = inst->opcode;
5582
6.18M
  if (!opcode->constraints && !insn_sequence->instr)
5583
5.95M
    return ERR_OK;
5584
5585
6.18M
  assert (insn_sequence);
5586
5587
232k
  enum err_type res = ERR_OK;
5588
5589
  /* This instruction puts a constraint on the insn_sequence.  */
5590
232k
  if (opcode->flags & F_SCAN)
5591
8.61k
    {
5592
8.61k
      if (insn_sequence->instr)
5593
881
  {
5594
881
    mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5595
881
    mismatch_detail->error = _("instruction opens new dependency "
5596
881
             "sequence without ending previous one");
5597
881
    mismatch_detail->index = -1;
5598
881
    mismatch_detail->non_fatal = true;
5599
881
    res = ERR_VFI;
5600
881
  }
5601
5602
8.61k
      init_insn_sequence (inst, insn_sequence);
5603
8.61k
      return res;
5604
8.61k
    }
5605
5606
232k
  bool is_new_section = (!encoding && pc == 0);
5607
223k
  if (!verify_mops_pme_sequence (inst, is_new_section, mismatch_detail,
5608
223k
         insn_sequence))
5609
7.27k
    {
5610
7.27k
      res = ERR_VFI;
5611
7.27k
      if ((opcode->constraints & C_SCAN_MOPS_PME) != C_SCAN_MOPS_M)
5612
5.35k
  init_insn_sequence (NULL, insn_sequence);
5613
7.27k
    }
5614
5615
  /* Verify constraints on an existing sequence.  */
5616
223k
  if (insn_sequence->instr)
5617
4.28k
    {
5618
4.28k
      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.28k
      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.28k
      if (inst_opcode->constraints & C_SCAN_MOVPRFX)
5635
3.88k
  {
5636
    /* Check to see if the MOVPRFX SVE instruction is followed by an SVE
5637
       instruction for better error messages.  */
5638
3.88k
    bool sve_operand_p = false;
5639
13.7k
    for (int i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
5640
12.3k
      {
5641
12.3k
        enum aarch64_operand_class op_class
5642
12.3k
    = aarch64_get_operand_class (opcode->operands[i]);
5643
12.3k
        if (op_class == AARCH64_OPND_CLASS_SVE_REG
5644
10.4k
      || op_class == AARCH64_OPND_CLASS_SVE_REGLIST
5645
10.0k
      || op_class == AARCH64_OPND_CLASS_PRED_REG)
5646
2.47k
    {
5647
2.47k
      sve_operand_p = true;
5648
2.47k
      break;
5649
2.47k
    }
5650
12.3k
      }
5651
5652
3.88k
    if (!sve_operand_p)
5653
1.40k
      {
5654
1.40k
        mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5655
1.40k
        mismatch_detail->error = _("SVE instruction expected after "
5656
1.40k
           "`movprfx'");
5657
1.40k
        mismatch_detail->index = -1;
5658
1.40k
        mismatch_detail->non_fatal = true;
5659
1.40k
        res = ERR_VFI;
5660
1.40k
        goto done;
5661
1.40k
      }
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.47k
    if (!(opcode->constraints & C_SCAN_MOVPRFX))
5666
779
      {
5667
779
        mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5668
779
        mismatch_detail->error = _("SVE `movprfx' compatible instruction "
5669
779
           "expected");
5670
779
        mismatch_detail->index = -1;
5671
779
        mismatch_detail->non_fatal = true;
5672
779
        res = ERR_VFI;
5673
779
        goto done;
5674
779
      }
5675
5676
    /* Next check for usage of the predicate register.  */
5677
1.69k
    aarch64_opnd_info blk_dest = insn_sequence->instr->operands[0];
5678
1.69k
    aarch64_opnd_info blk_pred, inst_pred;
5679
1.69k
    memset (&blk_pred, 0, sizeof (aarch64_opnd_info));
5680
1.69k
    memset (&inst_pred, 0, sizeof (aarch64_opnd_info));
5681
1.69k
    bool predicated = false;
5682
1.69k
    assert (blk_dest.type == AARCH64_OPND_SVE_Zd);
5683
5684
    /* Determine if the movprfx instruction used is predicated or not.  */
5685
1.69k
    if (insn_sequence->instr->operands[1].type == AARCH64_OPND_SVE_Pg3)
5686
1.47k
      {
5687
1.47k
        predicated = true;
5688
1.47k
        blk_pred = insn_sequence->instr->operands[1];
5689
1.47k
      }
5690
5691
1.69k
    unsigned char max_elem_size = 0;
5692
1.69k
    unsigned char current_elem_size;
5693
1.69k
    int num_op_used = 0, last_op_usage = 0;
5694
1.69k
    int i, inst_pred_idx = -1;
5695
1.69k
    int num_ops = aarch64_num_of_operands (opcode);
5696
7.69k
    for (i = 0; i < num_ops; i++)
5697
5.99k
      {
5698
5.99k
        aarch64_opnd_info inst_op = inst->operands[i];
5699
5.99k
        switch (inst_op.type)
5700
5.99k
    {
5701
2.05k
      case AARCH64_OPND_SVE_Zd:
5702
2.80k
      case AARCH64_OPND_SVE_Zm_5:
5703
2.99k
      case AARCH64_OPND_SVE_Zm_16:
5704
3.56k
      case AARCH64_OPND_SVE_Zn:
5705
3.56k
      case AARCH64_OPND_SVE_Zt:
5706
3.61k
      case AARCH64_OPND_SVE_Vm:
5707
3.71k
      case AARCH64_OPND_SVE_Vn:
5708
3.71k
      case AARCH64_OPND_Va:
5709
3.71k
      case AARCH64_OPND_Vn:
5710
3.71k
      case AARCH64_OPND_Vm:
5711
3.71k
      case AARCH64_OPND_Sn:
5712
3.71k
      case AARCH64_OPND_Sm:
5713
3.71k
        if (inst_op.reg.regno == blk_dest.reg.regno)
5714
922
          {
5715
922
      num_op_used++;
5716
922
      last_op_usage = i;
5717
922
          }
5718
3.71k
        current_elem_size
5719
3.71k
          = aarch64_get_qualifier_esize (inst_op.qualifier);
5720
3.71k
        if (current_elem_size > max_elem_size)
5721
1.69k
          max_elem_size = current_elem_size;
5722
3.71k
        break;
5723
0
      case AARCH64_OPND_SVE_Pd:
5724
1.15k
      case AARCH64_OPND_SVE_Pg3:
5725
1.15k
      case AARCH64_OPND_SVE_Pg4_5:
5726
1.15k
      case AARCH64_OPND_SVE_Pg4_10:
5727
1.34k
      case AARCH64_OPND_SVE_Pg4_16:
5728
1.34k
      case AARCH64_OPND_SVE_Pm:
5729
1.34k
      case AARCH64_OPND_SVE_Pn:
5730
1.34k
      case AARCH64_OPND_SVE_Pt:
5731
1.34k
      case AARCH64_OPND_SME_Pm:
5732
1.34k
        inst_pred = inst_op;
5733
1.34k
        inst_pred_idx = i;
5734
1.34k
        break;
5735
942
      default:
5736
942
        break;
5737
5.99k
    }
5738
5.99k
      }
5739
5740
1.69k
     assert (max_elem_size != 0);
5741
1.69k
     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.69k
     current_elem_size
5745
1.69k
       = opcode->constraints & C_MAX_ELEM
5746
1.69k
         ? max_elem_size
5747
1.69k
         : aarch64_get_qualifier_esize (inst_dest.qualifier);
5748
5749
    /* If movprfx is predicated do some extra checks.  */
5750
1.69k
    if (predicated)
5751
1.47k
      {
5752
        /* The instruction must be predicated.  */
5753
1.47k
        if (inst_pred_idx < 0)
5754
350
    {
5755
350
      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5756
350
      mismatch_detail->error = _("predicated instruction expected "
5757
350
               "after `movprfx'");
5758
350
      mismatch_detail->index = -1;
5759
350
      mismatch_detail->non_fatal = true;
5760
350
      res = ERR_VFI;
5761
350
      goto done;
5762
350
    }
5763
5764
        /* The instruction must have a merging predicate.  */
5765
1.12k
        if (inst_pred.qualifier != AARCH64_OPND_QLF_P_M)
5766
31
    {
5767
31
      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5768
31
      mismatch_detail->error = _("merging predicate expected due "
5769
31
               "to preceding `movprfx'");
5770
31
      mismatch_detail->index = inst_pred_idx;
5771
31
      mismatch_detail->non_fatal = true;
5772
31
      res = ERR_VFI;
5773
31
      goto done;
5774
31
    }
5775
5776
        /* The same register must be used in instruction.  */
5777
1.09k
        if (blk_pred.reg.regno != inst_pred.reg.regno)
5778
624
    {
5779
624
      mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5780
624
      mismatch_detail->error = _("predicate register differs "
5781
624
               "from that in preceding "
5782
624
               "`movprfx'");
5783
624
      mismatch_detail->index = inst_pred_idx;
5784
624
      mismatch_detail->non_fatal = true;
5785
624
      res = ERR_VFI;
5786
624
      goto done;
5787
624
    }
5788
1.09k
      }
5789
5790
    /* Destructive operations by definition must allow one usage of the
5791
       same register.  */
5792
689
    int allowed_usage
5793
689
      = aarch64_is_destructive_by_operands (opcode) ? 2 : 1;
5794
5795
    /* Operand is not used at all.  */
5796
689
    if (num_op_used == 0)
5797
134
      {
5798
134
        mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5799
134
        mismatch_detail->error = _("output register of preceding "
5800
134
           "`movprfx' not used in current "
5801
134
           "instruction");
5802
134
        mismatch_detail->index = 0;
5803
134
        mismatch_detail->non_fatal = true;
5804
134
        res = ERR_VFI;
5805
134
        goto done;
5806
134
      }
5807
5808
    /* We now know it's used, now determine exactly where it's used.  */
5809
555
    if (blk_dest.reg.regno != inst_dest.reg.regno)
5810
70
      {
5811
70
        mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5812
70
        mismatch_detail->error = _("output register of preceding "
5813
70
           "`movprfx' expected as output");
5814
70
        mismatch_detail->index = 0;
5815
70
        mismatch_detail->non_fatal = true;
5816
70
        res = ERR_VFI;
5817
70
        goto done;
5818
70
      }
5819
5820
    /* Operand used more than allowed for the specific opcode type.  */
5821
485
    if (num_op_used > allowed_usage)
5822
111
      {
5823
111
        mismatch_detail->kind = AARCH64_OPDE_SYNTAX_ERROR;
5824
111
        mismatch_detail->error = _("output register of preceding "
5825
111
           "`movprfx' used as input");
5826
111
        mismatch_detail->index = last_op_usage;
5827
111
        mismatch_detail->non_fatal = true;
5828
111
        res = ERR_VFI;
5829
111
        goto done;
5830
111
      }
5831
5832
    /* Now the only thing left is the qualifiers checks.  The register
5833
       must have the same maximum element size.  */
5834
374
    if (inst_dest.qualifier != AARCH64_OPND_QLF_NIL
5835
374
        && blk_dest.qualifier != AARCH64_OPND_QLF_NIL
5836
161
        && current_elem_size
5837
161
     != 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
374
  }
5848
5849
4.28k
    done:
5850
4.28k
      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
404
      else
5855
404
  add_insn_to_sequence (inst, insn_sequence);
5856
4.28k
    }
5857
5858
223k
  return res;
5859
223k
}
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
7.95k
{
5869
7.95k
  int64_t svalue = uvalue;
5870
7.95k
  uint64_t upper = (uint64_t) -1 << (esize * 4) << (esize * 4);
5871
5872
7.95k
  if ((uvalue & ~upper) != uvalue && (uvalue | upper) != uvalue)
5873
0
    return false;
5874
7.95k
  if (esize <= 4 || (uint32_t) uvalue == (uint32_t) (uvalue >> 32))
5875
6.94k
    {
5876
6.94k
      svalue = (int32_t) uvalue;
5877
6.94k
      if (esize <= 2 || (uint16_t) uvalue == (uint16_t) (uvalue >> 16))
5878
1.80k
  {
5879
1.80k
    svalue = (int16_t) uvalue;
5880
1.80k
    if (esize == 1 || (uint8_t) uvalue == (uint8_t) (uvalue >> 8))
5881
884
      return false;
5882
1.80k
  }
5883
6.94k
    }
5884
7.07k
  if ((svalue & 0xff) == 0)
5885
2.89k
    svalue /= 256;
5886
7.07k
  return svalue < -128 || svalue >= 128;
5887
7.95k
}
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"